Site Characteristics
site_temps = full_data %>%
dplyr::select(site, lat, season, doy, collection_temp, collection_salinity) %>%
distinct() %>%
filter(doy > 100)
Copepods were collected by surface tow from sites across the Western
Atlantic at several times throughout the year. The sites are shown
below. Temperatures at the time of collection were measured using a
manual thermometer. Across the entire set of collections, temperature
ranged from 10°C to 36°C.
coords = site_data %>%
dplyr::select(site, long, lat) %>%
distinct()
site_map = map_data("world") %>%
filter(region %in% c("USA", "Canada")) %>%
ggplot() +
geom_polygon(aes(x = long, y = lat, group = group),
fill = "lightgrey") +
coord_map(xlim = c(-85,-60),
ylim = c(25, 48)) +
geom_point(data = coords,
mapping = aes(x = long, y = lat, colour = site),
size = 3) +
scale_colour_manual(values = site_cols) +
labs(x = "Longitude",
y = "Latitude") +
theme_matt(base_size = 16)
site_temp_plot = ggplot(site_temps, aes(x = doy, y = collection_temp, colour = site)) +
geom_line(linewidth = 2) +
geom_point(size = 5) +
scale_colour_manual(values = site_cols) +
labs(y = "Temperature (°C)",
x = "Day of the Year") +
theme_matt() +
theme(legend.position = "right")
ggarrange(site_map, site_temp_plot, common.legend = T, legend = "bottom")

Collections aimed to obtain copepods near the onset of peak
temperatures, after peak temperatures, and then at low temperatures.
Regional data is not available for all sites, so here we’ve pieced
together daily temperature values from either local temperature sensors
(sites in Florida and the Chesapeake) and high resolution satellite
temperature data (Connecticut, Maine, and the Canadian sites). This
satellite data comes from the NOAA 1/4° Daily Optimum Interpolation Sea
Surface Temperature (OISST).
These temperature profiles are shown below, with the temperatures
measured during the time of collection included for comparison In
several cases collection temperature does not match the recorded daily
averages, but the temperature records do give a general sense of the
timing of seasonal maxima. In general, the first sample from each site
fell just after the site reached the warmest period. The exception to
that pattern is in Florida, where collections occurred after an extended
period of high temperatures.
temp_profiles = temp_profiles %>%
filter(doy > 100) %>%
mutate(region = fct_relevel(region, "Florida", "Chesapeake", "Connecticut",
"Maine", "Shediac", "Miramichi"))
site_temps2 = site_temps %>%
mutate(region = case_when(
site == "Manatee River" ~ "Florida",
site == "Ft. Hamer" ~ "Florida",
site == "Tyler Cove" ~ "Chesapeake",
site == "Ganey's Wharf" ~ "Chesapeake",
site == "Esker Point" ~ "Connecticut",
site == "Sawyer Park" ~ "Maine",
site == "St. Thomas de Kent Wharf" ~ "Shediac",
site == "Ritchie Wharf" ~ "Miramichi"),
region = fct_relevel(region, "Florida", "Chesapeake", "Connecticut",
"Maine", "Shediac", "Miramichi"))
ggplot(temp_profiles, aes(x = doy, y = temp_c)) +
facet_wrap(region~.) +
geom_point(data = site_temps2,
aes(x = doy, y = collection_temp, colour = site),
size = 3) +
geom_line() +
scale_colour_manual(values = site_cols) +
labs(x = "Day of the Year",
y = "Mean Daily Temp. (°C)") +
theme_matt_facets() +
theme(legend.position = "none",
axis.text.x = element_text(angle = 320, hjust = 0, vjust = 0.5))

Exact locations for the sites are provided here.
site_data %>%
arrange(lat) %>%
select("Site" = site, "Region" = region, "Lat" = lat, "Long" = long) %>%
knitr::kable(align = "c")
| Key Largo |
Florida |
25.28391 |
-80.33014 |
| Manatee River |
Florida |
27.50561 |
-82.57277 |
| Ft. Hamer |
Florida |
27.52488 |
-82.43101 |
| Tyler Cove |
Maryland |
38.35083 |
-76.22902 |
| Ganey’s Wharf |
Maryland |
38.80555 |
-75.90906 |
| Esker Point |
Connecticut |
41.32081 |
-72.00166 |
| Sawyer Park |
Maine |
43.90698 |
-69.87179 |
| St. Thomas de Kent Wharf |
New Brunswick |
46.44761 |
-64.63692 |
| Ritchie Wharf |
New Brunswick |
47.00481 |
-65.56291 |
Nested within each of the three regions (South, Central, and Northern
regions) are pairs of low and high salinity sites:
data.frame("Region" = c("South", "Central", "North"),
"Low Salinity" = c("Ft. Hamer", "Ganey's Wharf", "Ritchie Wharf"),
"High Salinity" = c("Manatee River", "Tyler Cove", "St. Thomas de Kent Wharf")) %>%
knitr::kable(align = "c")
| South |
Ft. Hamer |
Manatee River |
| Central |
Ganey’s Wharf |
Tyler Cove |
| North |
Ritchie Wharf |
St. Thomas de Kent Wharf |
There are fairly well-established divergences between high salinity
and low salinity populations of Acartia tonsa. These sets of
geographically proximate but isolated populations provide independent
comparisons of the effects of seasonality. Shown here are the collection
conditions for these pairs of sites. Temperature was typically similar
across the pairs within each collection, while salinity differences were
fairly stable across collections.
season_cols = c("early" = "grey75",
"peak" = "grey50",
"late" = "grey25")
sal_regions = data.frame(region = rep(c("South", "Central", "North"), each = 2),
site = c("Ft. Hamer", "Manatee River",
"Ganey's Wharf", "Tyler Cove",
"Ritchie Wharf", "St. Thomas de Kent Wharf"),
salinity = c("low", "high"))
sal_comps = full_data %>%
filter(site %in% sal_regions$site) %>%
inner_join(sal_regions, by = c("site")) %>%
select( region = region.y, site, salinity, season, doy, collection_temp, collection_salinity,
size, ctmax, warming_tol) %>%
mutate(salinity = fct_relevel(salinity, "low", "high"),
region = fct_relevel(region, "South", "Central", "North"))
sal_comp_temps = sal_comps %>%
select(salinity, season, region, collection_temp, collection_salinity) %>%
distinct() %>%
ggplot(aes(x = salinity, y = collection_temp, colour = season, group = season)) +
facet_wrap(region~.) +
geom_line(linewidth = 1.5) +
geom_point(size = 4) +
scale_colour_manual(values = season_cols) +
labs(y = "Collection Temp. (°C)",
x = "") +
theme_matt_facets(base_size = 14)
sal_comp_sal = sal_comps %>%
select(salinity, season, region, collection_temp, collection_salinity) %>%
distinct() %>%
ggplot(aes(x = salinity, y = collection_salinity, colour = season, group = season)) +
facet_wrap(region~.) +
geom_line(linewidth = 1.5) +
geom_point(size = 4) +
scale_colour_manual(values = season_cols) +
labs(y = "Collection Salinity (psu)",
x = "Salinity") +
theme_matt_facets(base_size = 14)
ggarrange(sal_comp_temps, sal_comp_sal, nrow = 2, common.legend = T, legend = "right")

The latitudinal gradient covers a wide range of seasonality. Shown
below is the temperature range. While based on collection temperatures,
and therefore an underestimate of the total seasonal range of
temperatures, these patterns are representative of the expected
latitudinal gradient in seasonality.
site_temps %>%
group_by(site, lat) %>%
summarise(temp_range = max(collection_temp) - min(collection_temp)) %>%
ggplot(aes(x = lat, y = temp_range)) +
geom_point(aes(colour = site),
size = 3) +
scale_color_manual(values = site_cols) +
labs(x = "Latitude",
y = "Collection Temp. Range (°C)") +
theme_matt() +
theme(legend.position = "right")

Phenotypic Measurements
Critical Thermal Limits
A total of 456 individuals were examined. Critical thermal limits and
body size measurements were made before individuals were preserved in
ethanol. We excluded data for 7 individuals, detailed below. These
individuals had either very low CTmax or were, upon re-examination of
photographs, identified as juveniles instead of mature females. With
these individuals excluded, the full data set contains 449
phenotyped individuals.
excluded %>%
select(region, site, season, collection_temp, collection_salinity, replicate, tube, ctmax, size) %>%
knitr::kable(align = "c")
| Florida |
Manatee River |
peak |
34.0 |
29 |
2 |
6 |
38.45833 |
0.616 |
| Florida |
Manatee River |
peak |
34.0 |
29 |
2 |
7 |
38.23750 |
0.593 |
| Florida |
Ft. Hamer |
late |
20.0 |
18 |
2 |
3 |
36.59280 |
0.619 |
| Maryland |
Tyler Cove |
peak |
29.5 |
15 |
2 |
2 |
36.84375 |
0.614 |
| Connecticut |
Esker Point |
early |
22.5 |
30 |
2 |
3 |
30.02604 |
0.687 |
| Maine |
Sawyer Park |
peak |
22.0 |
30 |
1 |
4 |
30.81424 |
0.865 |
| New Brunswick |
St. Thomas de Kent Wharf |
late |
13.5 |
28 |
1 |
3 |
28.78299 |
1.039 |
Critical thermal maxima (CTmax) was measured using a custom setup.
The method uses a standard dynamic ramping assay to determine the
maximum temperature individuals could sustain normal functioning. This
differs from lethal temperatures, and indeed, all individuals observed
so far recovered following the assay.
Individuals were rested for one hour after collection before the
assay. During the assay, copepods were held in artificial seawater,
composed of bottled spring water and Instant Ocean salt mix adjusted to
match collection salinities. During the assay, several ‘control’
individuals were maintained in this solution at ambient temperatures
without the temperature ramp to ensure that there was no background
mortality. When sorting individuals from the plankton tow contents, they
were held in a 50:50 mix of 60 um filtered water from the collection
site and artificial seawater as an additional acclimation step.
Sample sizes varied slightly across experiments, but most sites had
20 individuals measured per season. The major exceptions were the early
samples from the Florida sites and the late sample from Sawyer Park
(Maine). Only two sets of samples (peak and late) were collected from
Fort Hamer and Manatee River. No samples were collected from Key Largo
for this project, as Acartia tonsa wasn’t present in the water
during the peak season, likely due to the recent extreme heat event. The
late season collection from Sawyer Park occurred after Acartia
tonsa abundance decreased. Samples from this period were dominated
by Acartia hudsonica instead.
ggplot(full_data, aes(x = site, fill = site)) +
facet_wrap(season~.) +
geom_hline(yintercept = c(0,20),
colour = "grey70") +
geom_bar() +
scale_fill_manual(values = site_cols) +
coord_flip() +
theme_matt() +
theme(legend.position = "none",
panel.border = element_rect(linewidth = 1,
fill = NA),
strip.text = element_text(size = 20),
axis.title.y = element_blank())

Shown below are the measured CTmax values. Note: CTmax values for the
early season Key Largo copepods were collected at the end of February
2023 as part of a separate project. Body size values were not measured
during this project, nor were copepods individually preserved after the
experiments. These early season CTmax values are included as a point of
comparison. Individual measurements are shown in small points for each
collection. The large points indicate the mean values for each
collection.
mean_ctmax = full_data %>%
group_by(site, season, doy, collection_temp) %>%
summarize(mean_ctmax = mean(ctmax),
median_ctmax = median(ctmax))
ctmax_plot = ggplot(full_data, aes(x = season, y = ctmax, colour = site)) +
geom_line(data = mean_ctmax,
aes(y = mean_ctmax, group = site),
position = position_dodge(width = 0.4),
linewidth = 1) +
geom_point(position = position_jitterdodge(jitter.width = 0.1, jitter.height = 0,
dodge.width = 0.4),
alpha = 0.3) +
geom_point(data = mean_ctmax,
aes(y = mean_ctmax),
position = position_dodge(width = 0.4),
size = 4) +
scale_colour_manual(values = site_cols) +
labs(y = "CTmax (°C)",
x = "Season") +
theme_matt() +
theme(legend.position = "right",
legend.title.align = 0.125)
ctmax_plot

Warming tolerance
Warming tolerance (the difference between thermal limits and
environmental temperatures) is a commonly used metric of climate
vulnerability. We calculated this as the difference between measured
CTmax values and the collection temperature. Smaller warming tolerance
values indicate that populations were nearer to their upper thermal
limits, and may therefore be more vulnerable to additional warming.
mean_wt = full_data %>%
group_by(site, season) %>%
summarize(mean_wt = mean(warming_tol),
median_wt = median(warming_tol))
ggplot(full_data, aes(x = season, y = warming_tol, colour = site)) +
geom_line(data = mean_wt,
aes(y = mean_wt, group = site),
position = position_dodge(width = 0.4),
linewidth = 1) +
geom_point(position = position_jitterdodge(jitter.width = 0.1, jitter.height = 0,
dodge.width = 0.4),
alpha = 0.3) +
geom_point(data = mean_wt,
aes(y = mean_wt),
position = position_dodge(width = 0.4),
size = 4) +
scale_colour_manual(values = site_cols) +
labs(y = "Warming Tolerance (°C)",
x = "Season") +
theme_matt() +
theme(legend.position = "right",
legend.title.align = 0.125)

Body Size
Following the CTmax assay, individuals were photographed for body
size measurements. Prosome lengths were measured from these photographs
using a scale micrometer and the software ImageJ. These measurements are
shown below. As before, large points indicate the mean body size. While
less cohesive than CTmax, a general trend of increasing body size with
latitude and time of year can be seen.
mean_size = full_data %>%
group_by(site, season, doy, collection_temp) %>%
summarize(mean_size = mean(size),
median_size = median(size))
ggplot(full_data, aes(x = season, y = size, colour = site)) +
geom_line(data = mean_size,
aes(y = mean_size, group = site),
position = position_dodge(width = 0.4),
linewidth = 1) +
geom_point(position = position_jitterdodge(jitter.width = 0.1, jitter.height = 0,
dodge.width = 0.4),
alpha = 0.3) +
geom_point(data = mean_size,
aes(y = mean_size),
position = position_dodge(width = 0.4),
size = 4) +
scale_colour_manual(values = site_cols) +
labs(y = "Prosome Length (mm)",
x = "Season") +
theme_matt() +
theme(legend.position = "right",
legend.title.align = 0.125)

Salinity Pair Comparisons
The three pairs of cross-salinity comparisons do show evidence for
fine-scale trait divergence, although there was no consistent pattern in
the direction or magnitude of differences. CTmax was similar across
sites in the Southern and Central pairs. In the Northern pair, CTmax
tended to be slightly lower for individuals from the low salinity site.
Size was more variable between the paired sites. In the South, low
salinity individuals were consistently smaller than high salinity
individuals, despite experiencing similar temperatures. In the Central
pair, individuals from the low salinity site tended to be slightly
larger than those from the high salinity site, although this varied
seasonally. Sizes tended to be more similar across the collections from
the Northern pair.
sal_comp_ctmax_plot = sal_comps %>%
ggplot(aes(x = salinity, y = ctmax, colour = season, group = season)) +
facet_wrap(region~.) +
geom_point(size = 2,
position = position_dodge(width = 0.2)) +
#geom_line(size = 1.5) +
scale_colour_manual(values = season_cols) +
labs(y = "CTmax (°C)",
x = "") +
theme_matt_facets(base_size = 14)
sal_comp_size_plot = sal_comps %>%
ggplot(aes(x = salinity, y = size, colour = season, group = season)) +
facet_wrap(region~.) +
geom_point(size = 2,
position = position_dodge(width = 0.2)) +
#geom_line(size = 1.5) +
scale_colour_manual(values = season_cols) +
labs(y = "Prosome Length (mm)",
x = "") +
theme_matt_facets(base_size = 14)
ggarrange(sal_comp_ctmax_plot, sal_comp_size_plot, nrow = 2, common.legend = T, legend = "right")

###
#
# sal_comp_ctmax.model = lm(ctmax ~ collection_temp, data = sal_comps)
# # summary(ctmax_temp.model)
# # car::Anova(ctmax_temp.model)
# sal_comp_ctmax_resids = residuals(sal_comp_ctmax.model)
#
# sal_comp_size.model = lm(size ~ collection_temp, data = sal_comps)
# # summary(size_temp.model)
# # car::Anova(size_temp.model)
# sal_comp_size_resids = residuals(sal_comp_size.model)
#
# sal_comp_ctmax_resid_plot = sal_comps %>%
# mutate(ctmax_resids = sal_comp_ctmax_resids,
# size_resids = sal_comp_size_resids) %>%
# ggplot(aes(x = salinity, y = ctmax_resids, colour = season, group = season)) +
# facet_wrap(region~.) +
# geom_point(size = 2,
# position = position_dodge(width = 0.5)) +
# #geom_line(size = 1.5) +
# scale_colour_manual(values = season_cols) +
# labs(y = "CTmax \nResiduals",
# x = "") +
# theme_matt_facets(base_size = 14)
#
# sal_comp_size_resid_plot = sal_comps %>%
# mutate(ctmax_resids = sal_comp_ctmax_resids,
# size_resids = sal_comp_size_resids) %>%
# ggplot(aes(x = salinity, y = size_resids, colour = season, group = season)) +
# facet_wrap(region~.) +
# geom_point(size = 2,
# position = position_dodge(width = 0.5)) +
# #geom_line(size = 1.5) +
# scale_colour_manual(values = season_cols) +
# labs(y = "Prosome Length \nResiduals",
# x = "") +
# theme_matt_facets(base_size = 14)
#
# ggarrange(sal_comp_ctmax_resid_plot, sal_comp_size_resid_plot, nrow = 2, common.legend = T, legend = "right")
Trait Correlations
Regardless of the underlying mechanism (genetic differentiation or
phenotypic plasticity), we expect that collections from warmer waters
should yield copepods with higher thermal limits and smaller body sizes.
Our observations largely fit this expectation, with strong increases in
CTmax at higher temperatures, and a general decrease in prosome lengths
as temperature increased. There was a larger correlation between CTmax
and temperature than size and temperature. There are myriad reasons this
might be observed, but one potential is the potential for acclimation of
thermal limits. Body size is fixed in the adult stage, while CTmax can
continue to vary as water temperature changes. This is indirect evidence
for the importance of rapid acclimation in the observed patterns.
ctmax_temp_plot = ggplot(full_data, aes(x = collection_temp, y = ctmax)) +
geom_smooth(method = "lm", se = T,
linewidth = 2,
colour = "grey") +
geom_point(aes(colour = site),
size = 2, alpha = 0.7) +
scale_colour_manual(values = site_cols) +
labs(y = "CTmax (°C)",
x = "Collection Temp. (°C)") +
theme_matt() +
theme(legend.position = "none")
size_temp_plot = ggplot(full_data, aes(x = collection_temp, y = size)) +
geom_smooth(method = "lm", se = T,
linewidth = 2,
colour = "grey") +
geom_point(aes(colour = site),
size = 2, alpha = 0.7) +
scale_colour_manual(values = site_cols) +
labs(y = "Prosome Length (mm)",
x = "Collection Temp. (°C)") +
theme_matt() +
theme(legend.position = "right")
wt_temp_plot = ggplot(full_data, aes(x = collection_temp, y = warming_tol)) +
geom_smooth(method = "lm", se = T,
linewidth = 2,
colour = "grey") +
geom_point(aes(colour = site),
size = 2, alpha = 0.7) +
scale_colour_manual(values = site_cols) +
labs(y = "Warming Tolerance (°C)",
x = "Collection Temp. (°C)") +
theme_matt() +
theme(legend.position = "right")
ggarrange(ctmax_temp_plot, wt_temp_plot, size_temp_plot, common.legend = T, legend = "bottom", nrow = 1)

One additional correlation of interest is the relationship between
prosome length and CTmax. In many cases, larger body sizes are
associated with cold adaptation/acclimation, and there is a general
trend of decreasing thermal limits with increasing size. Shown below is
the relationship between prosome length and CTmax in our data set.
Individual regression lines for each site are also included - the dark
grey lines in the background represent the ‘universal’ regression for
that site, with individual colored regression lines for each collection.
Across our collections, we see evidence for this relationship, with
larger individuals having lower thermal limits.
universal_size = full_data %>%
ggplot(aes(x = size, y = ctmax)) +
# geom_smooth(data = filter(full_data, ctmax > 31),
# aes(x = size, y = ctmax),
# method = "lm",
# colour = "grey60",
# se = F,
# linewidth = 2) +
geom_smooth(method = "lm", se = T,
linewidth = 2,
colour = "grey70") +
geom_point(aes(colour = site),
size = 2, alpha = 0.7) +
scale_colour_manual(values = site_cols) +
labs(y = "CTmax (°C)",
x = "") +
theme_matt(base_size = 14) +
theme(legend.position = "right",
axis.title.x = element_blank())
pop_size = full_data %>%
ggplot(aes(x = size, y = ctmax, colour = site, group = season)) +
facet_wrap(site~.) +
# geom_smooth(data = filter(full_data, ctmax > 31),
# aes(x = size, y = ctmax),
# method = "lm",
# colour = "grey60",
# se = F,
# linewidth = 2) +
geom_smooth(data = full_data,
aes(x = size, y = ctmax, group = site),
colour = "grey20", method = "lm", se = F) +
geom_point(size = 1.3, alpha = 0.3) +
geom_smooth(method = "lm", se = F,
linewidth = 1) +
scale_colour_manual(values = site_cols) +
scale_x_continuous(breaks = c(0.6, 0.8, 1)) +
labs(y = "CTmax (°C)",
x = "Prosome Length (mm)") +
theme_matt(base_size = 14) +
theme(legend.position = "right")
ggarrange(universal_size, pop_size, common.legend = T, legend = "none", nrow = 2)

This relationship may be affected by changes in temperature at each
site, however, which can affect both body size and thermal limits. If
there is a true mechanistic relationship between body size and thermal
limits, we would expect to see this relationship emerge
within populations, or even individual collections.
Shown below is the relationship between CTmax and size residuals,
acquired from regressions of these traits against collection
temperature. This substantially reduces the strength of the apparent
relationship, but there is still a slightly negative overall
relationship, spanning both across-population, within-population, and
even within-collection scales (see the Sawyer Park collections, for
example).
filtered_data = full_data %>%
drop_na(size, ctmax) %>%
mutate(temp_cent = scale(collection_temp, scale = F),
size_cent = scale(size, scale = F),
sal_cent = scale(collection_salinity, scale = F),
sal_type = if_else(collection_salinity > 20, "High", "Low"))
ctmax_temp.model = lm(ctmax ~ collection_temp + site, data = filtered_data)
ctmax_resids = residuals(ctmax_temp.model)
size_temp.model = lm(size ~ collection_temp + site, data = filtered_data)
size_resids = residuals(size_temp.model)
universal_resids = filtered_data %>%
mutate(ctmax_resids = ctmax_resids,
size_resids = size_resids)
all_resids = ggplot(universal_resids, aes(x = size_resids, y = ctmax_resids)) +
# geom_smooth(data = filter(full_data, ctmax > 31),
# aes(x = size, y = ctmax),
# method = "lm",
# colour = "grey60",
# se = F,
# linewidth = 2) +
geom_smooth(method = "lm", se = T,
linewidth = 2,
colour = "grey70") +
geom_point(aes(colour = site),
size = 2, alpha = 0.7) +
scale_colour_manual(values = site_cols) +
labs(y = "CTmax Residuals",
x = "") +
theme_matt(base_size = 14) +
theme(legend.position = "right",
axis.title.x = element_blank())
pop_resids = ggplot(universal_resids, aes(x = size_resids, y = ctmax_resids, colour = site, group = season)) +
facet_wrap(site~.) +
# geom_smooth(data = filter(full_data, ctmax > 31),
# aes(x = size, y = ctmax),
# method = "lm",
# colour = "grey60",
# se = F,
# linewidth = 2) +
geom_smooth(aes(x = size_resids, y = ctmax_resids, group = site),
colour = "grey20", method = "lm", se = F) +
geom_point(size = 1.3, alpha = 0.3) +
geom_smooth(method = "lm", se = F,
linewidth = 1) +
scale_colour_manual(values = site_cols) +
labs(y = "CTmax Residuals",
x = "Prosome Length Residuals") +
theme_matt(base_size = 14) +
theme(legend.position = "right")
ggarrange(all_resids, pop_resids, common.legend = T, legend = "none", nrow = 2)

To more formally test the relationships between CTmax, collection
temperature, and size, we used a linear mixed effects model, structured
as
ctmax ~ collection temp. + size + salinity + (1 + collection temp.|site).
This examines the effects of temperature and size on CTmax, along with
differences between the salinity groupings. Collection temperature and
size were both centered and salinity transformed into a categorical
variable (“low” salinity as anything below 20 psu, “high” salinity as
anything above 20 psu) before model fitting. The model also includes
random intercepts for each site and random slopes for collection
temperature (i.e. - variation in the acclimation capacity of CTmax). A
random intercept for season is also included.
Collection temperature and body size both had a significant effect on
CTmax, but salinity type did not. The overall effect of temperature
suggests an increase in CTmax of 0.17°C per °C increase in collection
temperature (i.e. - an ARR value of 0.17), while increasing body sizes
decrease CTmax by -3.17°C per mm (or a decrease of ~-0.317°C per tenth
of a mm, which is more biologically realistic for A. tonsa).
While not significant, the model suggests low salinity sites had lower
thermal limits by ~0.7°C.
effects_summary = data.frame(
"Temperature" = unname(fixef(ctmax.model)["temp_cent"]),
"Size" = unname(fixef(ctmax.model)["size"]),
"Salinity" = unname(fixef(ctmax.model)["sal_typeLow"])) %>%
select("Temperature (per degree)" = Temperature,
"Size (per mm)" = Size,
"Salinity (Low vs. High)" = Salinity)
knitr::kable(effects_summary)
| 0.1664574 |
-3.165841 |
-0.6942512 |
By extracting the conditional mode for the random effects, we can
also examine how thermal limits vary across sites beyond the influence
of collection temperatures and body sizes. Shown below are these
“population” values (essentially, all else being equal, how would
thermal limit vary across populations). We can see that, similar to
what’s been observed in common garden experiments with A. tonsa
previously, significant divergences are present at only a few sites near
the latitudinal extremes, with Fort Hamer and Ritchie Wharf having
increased and decreased thermal limits respectively. Interestingly, both
of these sites were low salinity sites, also in line with previous
results suggesting gene flow between high salinity sites may constrain
differentiation.
pop_effs = REsim(ctmax.model) %>%
dplyr::select("site" = groupID, term, mean, sd) %>%
filter(term == "(Intercept)") %>%
inner_join(site_data, by = c("site")) %>%
mutate(site = fct_reorder(site, lat))
season_effs = REsim(ctmax.model) %>%
dplyr::select("site" = groupID, term, mean, sd) %>%
filter(site %in% c("early", "peak", "late")) %>%
select("season" = site, mean, sd)
#plotREsim(REsim(ctmax.model)) # plot the interval estimates
pop_effs_plot = ggplot(pop_effs, aes(x = lat, y = mean, colour = site)) +
geom_hline(yintercept = 0, colour = "grey") +
geom_errorbar(aes(ymin = mean - 1.96 * sd, ymax = mean + 1.96 * sd),
width = 0.5, linewidth = 1) +
geom_point(size = 3) +
scale_colour_manual(values = site_cols) +
labs(x = "Latitude",
y = "Population Effect") +
theme_matt() +
theme(legend.position = "right")
pop_effs_plot

Finally, shown below are the estimated random slopes for each site.
These represent the effects of collection temperature on CTmax for each
site. Interestingly, these estimates diverge from the results of
previous common garden experiments, which showed the strongest
plasticity in high latitude sites. Here, acclimation appears to peak in
mid-latitudes, and decrease at both high and low latitude sites. This
suggests factors may constrain acclimation capacity in natural
populations (e.g. food availability, environmental variation, pathogens,
etc.).
coefficients(ctmax.model)$site %>%
janitor::clean_names() %>%
rownames_to_column(var = "site") %>%
inner_join(site_data) %>%
mutate(site = fct_reorder(site, lat)) %>%
ggplot(aes(x = temp_cent, y = site)) +
geom_point(aes(colour = site),
size = 5) +
scale_colour_manual(values = site_cols) +
labs(x = "ARR") +
theme_matt() +
theme(legend.position = "none",
axis.title.y = element_blank())

Trait Variability
Shown below is the trait variation (ranges) for each site. Ranges are
calculated for each collection separately.
trait_ranges = full_data %>%
group_by(site, season, collection_temp, collection_salinity, doy, lat) %>%
summarise(mean_ctmax = mean(ctmax),
ctmax_range = max(ctmax) - min(ctmax),
ctmax_var = var(ctmax),
mean_size = mean(size),
size_range = max(size) - min(size),
size_var = var(size)) %>%
mutate(prop_ctmax_range = ctmax_range / mean_ctmax,
prop_size_range = size_range / mean_size)
ctmax_range_temp = ggplot(trait_ranges, aes(x = collection_temp, y = ctmax_range)) +
geom_smooth(method = "lm", colour = "black") +
geom_point(aes(colour = site),
size = 3) +
scale_colour_manual(values = site_cols) +
labs(y = "CTmax Range (°C)",
x = "Collection Temp. (°C)") +
theme_matt() +
theme(legend.position = "right")
ctmax_var_temp = ggplot(trait_ranges, aes(x = collection_temp, y = ctmax_var, colour = site)) +
geom_point(size = 3) +
scale_colour_manual(values = site_cols) +
labs(y = "CTmax Range (°C)",
x = "Collection Temp. (°C)") +
theme_matt() +
theme(legend.position = "right")
size_range_temp = ggplot(trait_ranges, aes(x = collection_temp, y = size_range, colour = site)) +
geom_point(size = 3) +
scale_colour_manual(values = site_cols) +
labs(y = "Size Range (mm)",
x = "Collection Temp. (°C)") +
theme_matt() +
theme(legend.position = "right")
size_var_temp = ggplot(trait_ranges, aes(x = collection_temp, y = size_var, colour = site)) +
geom_point(size = 3) +
scale_colour_manual(values = site_cols) +
labs(y = "Size Range (mm)",
x = "Collection Temp. (°C)") +
theme_matt() +
theme(legend.position = "right")
ggarrange(ctmax_range_temp, size_range_temp, common.legend = T, legend = "right")

Changes in trait variance may be indicative of phenotypic selection.
If selection (as opposed to acclimation) are driving seasonal changes,
we may expect to see a reduction in variance in the peak samples
relative to the early season samples. Note that early season collection
temperatures this year were higher than expected, driven by fairly
strong heatwaves across the North Atlantic. As shown in the temperature
profiles for each site, the ‘early’ samples were collected just after
high temperatures were reached, while ‘peak’ samples were collected
after sites had experienced high temperatures for several weeks
(generations). As warming tolerances were fairly high throughout this
period, we will assume that selection was weak before the early samples.
If the early onset of high temperatures filtered out vulnerable
genotypes prior to our sampling, the results will be a conservative
estimate of the effects of selection on trait variance.
Shown below is the seasonal progression of variance in CTmax for each
site. For many sites, variance decreased between the early and peak
samples, and then increased again in the late sample. For some sites
(e.g. Esker Point), this increase in the late sample was
substantial.
ggplot(trait_ranges, aes(x = season, y = ctmax_var, colour = site)) +
geom_line(aes(group = site),
linewidth = 1.5) +
geom_point(size = 3) +
scale_colour_manual(values = site_cols) +
labs(y = "CTmax Variance",
x = "Season") +
theme_matt() +
theme(legend.position = "right",
legend.title.align = 0.125)

Shown below is the seasonal progression of variance in body size. A
similar pattern of decreasing variance in peak samples relative to early
and late samples is again seen for many sites. The obvious exception is
the Esker Point sample, which saw the opposite trend.
ggplot(trait_ranges, aes(x = season, y = size_var, colour = site)) +
geom_line(aes(group = site),
linewidth = 1.5) +
geom_point(size = 3) +
scale_colour_manual(values = site_cols) +
labs(y = "CTmax Variance",
x = "Season") +
theme_matt() +
theme(legend.position = "right",
legend.title.align = 0.125)

Shown below are the seasonal changes in trait variance for each site
individually.
ggplot(trait_ranges, aes(x = season, y = ctmax_var, colour = site)) +
facet_wrap(site~.) +
geom_line(aes(group = site),
linewidth = 1.5) +
geom_point(size = 3) +
scale_colour_manual(values = site_cols) +
labs(y = "CTmax Variance",
x = "Season") +
theme_matt() +
theme(legend.position = "none",
legend.title.align = 0.125)

ggplot(trait_ranges, aes(x = season, y = size_var, colour = site)) +
facet_wrap(site~.) +
geom_line(aes(group = site),
linewidth = 1.5) +
geom_point(size = 3) +
scale_colour_manual(values = site_cols) +
labs(y = "Size Variance",
x = "Season") +
theme_matt() +
theme(legend.position = "none",
legend.title.align = 0.125)

knitr::knit_exit()
LS0tCnRpdGxlOiAiQ29tcGFyaW5nIHNlYXNvbmFsIGFuZCBsYXRpdHVkaW5hbCBwYXR0ZXJucyBpbiB0aGVybWFsIGFkYXB0YXRpb24iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgICAgICAgY29kZV9mb2xkaW5nOiBoaWRlCiAgICAgICAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICAgICAgICB0b2M6IHRydWUKICAgICAgICAgIHRvY19mbG9hdDogdHJ1ZQogIGdpdGh1Yl9kb2N1bWVudDoKICAgICAgICAgIGh0bWxfcHJldmlldzogZmFsc2UKICAgICAgICAgIHRvYzogdHJ1ZQogICAgICAgICAgdG9jX2RlcHRoOiAzCi0tLQoKYGBge3J9CiMgVE8gRE8gCiMgLSBGcmFtZXdvcmsgZm9yIHF1YW50aWZ5aW5nIHRoZSBlZmZlY3RzIG9mIHdpdGhpbi0gYW5kIGFjcm9zcy1wb3B1bGF0aW9uIHZhcmlhdGlvbiBpbiB0aGVybWFsIGxpbWl0cyB0byBzcGF0aWFsIHBhdHRlcm5zIGluIHZ1bG5lcmFiaWxpdHkgdG8gd2FybWluZy4gQ29tcGFyaW5nIHByZWRpY3Rpb25zIGJhc2VkIG9uIDEpIG1lZGlhbiwgMikgb3ZlcmFsbCBDVG1heCB2cy4gdGVtcCByZWdyZXNzaW9uLCAzKSBwb3B1bGF0aW9uIHZhcmlhdGlvbiBpbiBpbnRlcmNlcHRzLCA0KSBwb3B1bGF0aW9uIHZhcmlhdGlvbiBpbiBib3RoIHNsb3BlIGFuZCBpbnRlcmNlcHQuIFRoZSBlbmQgbWV0cmljIEkgY291bGQgdXNlIHRvIGNvbXBhcmUgYWNyb3NzIHNjZW5hcmlvcyBpcyBpKSB0aGUgY3VtdWxhdGl2ZSBhbW91bnQgb2YgdW5kZXJlc3RpbWF0aW9uIChzdW1tZWQgYWNyb3NzIHBvcHVsYXRpb25zKSBvciBpaSkgdGhlIG51bWJlciBvZiBzaXRlcyB0aGF0IGhhdmUgb3ZlcmVzdGltYXRlZCBXVCwgb3IgaWlpKSB0aGUgc2xvcGUgb2YgV1QgKGxvY2FsIGFkYXB0YXRpb24gYW5kIHNlYXNvbmFsIGFjY2xpbWF0aW9uIHNob3VsZCByZXN1bHQgaW4gbW9yZSBzaGFsbG93IHNsb3BlcykuIApgYGAKCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1ULCBtZXNzYWdlID0gRiwgd2FybmluZyA9IEYsIGVjaG8gPSBGfQoKa25pdHI6Om9wdHNfY2h1bmskc2V0KAogIGVjaG8gPSBrbml0cjo6aXNfaHRtbF9vdXRwdXQoKSwKICBmaWcuYWxpZ24gPSAiY2VudGVyIiwKICBmaWcucGF0aCA9ICIuLi9GaWd1cmVzL21hcmtkb3duLyIsCiAgZGV2ID0gYygicG5nIiwgInBkZiIpLAogIG1lc3NhZ2UgPSBGQUxTRSwKICB3YXJuaW5nID0gRkFMU0UsCiAgY29sbGFwc2UgPSBUCikKCnRoZW1lX21hdHQgPSBmdW5jdGlvbihiYXNlX3NpemUgPSAxOCwKICAgICAgICAgICAgICAgICAgICAgIGRhcmtfdGV4dCA9ICJncmV5MjAiKXsKICBtaWRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzJdCiAgbGlnaHRfdGV4dCA8LSAgbW9ub2Nocm9tZVI6OmdlbmVyYXRlX3BhbGV0dGUoZGFya190ZXh0LCAiZ29fbGlnaHRlciIsIG5fY29sb3VycyA9IDUpWzNdCiAgCiAgdGhlbWVfcHVicihiYXNlX2ZhbWlseT0ic2FucyIpICUrcmVwbGFjZSUgCiAgICB0aGVtZSgKICAgICAgcGFuZWwuYmFja2dyb3VuZCAgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLCAKICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwgCiAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwKICAgICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksCiAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gbWlkX3RleHQsIGxpbmVoZWlnaHQgPSAxLjEpLAogICAgICB0aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMS41LAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvdXIgPSBkYXJrX3RleHQpLAogICAgICBheGlzLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9IG1pZF90ZXh0KSwKICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSB1bml0KGMoMywgMCwgMCwgMCksICJtbSIpKSwKICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXJnaW4gPSB1bml0KGMoMCwgNSwgMCwgMCksICJtbSIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuZ2xlID0gOTApLAogICAgICBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPWJhc2Vfc2l6ZSAqIDAuOSksCiAgICAgIGxlZ2VuZC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplICogMC45LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhY2UgPSAiYm9sZCIpLAogICAgICBwbG90Lm1hcmdpbiA9IG1hcmdpbigwLjI1LCAwLjI1LCAwLjI1LCAwLjI1LCJjbSIpCiAgICApCn0KCnRoZW1lX21hdHRfZmFjZXRzID0gZnVuY3Rpb24oYmFzZV9zaXplID0gMTgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGFya190ZXh0ID0gImdyZXkyMCIpewogIG1pZF90ZXh0IDwtICBtb25vY2hyb21lUjo6Z2VuZXJhdGVfcGFsZXR0ZShkYXJrX3RleHQsICJnb19saWdodGVyIiwgbl9jb2xvdXJzID0gNSlbMl0KICBsaWdodF90ZXh0IDwtICBtb25vY2hyb21lUjo6Z2VuZXJhdGVfcGFsZXR0ZShkYXJrX3RleHQsICJnb19saWdodGVyIiwgbl9jb2xvdXJzID0gNSlbM10KICAKICB0aGVtZV9idyhiYXNlX2ZhbWlseT0ic2FucyIpICUrcmVwbGFjZSUgCiAgICB0aGVtZSgKICAgICAgcGFuZWwuZ3JpZCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgcGFuZWwuYmFja2dyb3VuZCAgPSBlbGVtZW50X3JlY3QoZmlsbD0idHJhbnNwYXJlbnQiLCBjb2xvdXI9TkEpLCAKICAgICAgcGxvdC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwgCiAgICAgIGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9InRyYW5zcGFyZW50IiwgY29sb3VyPU5BKSwKICAgICAgbGVnZW5kLmtleSA9IGVsZW1lbnRfcmVjdChmaWxsPSJ0cmFuc3BhcmVudCIsIGNvbG91cj1OQSksCiAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gbWlkX3RleHQsIGxpbmVoZWlnaHQgPSAxLjEpLAogICAgICBzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSksCiAgICAgIHRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAxLjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG91ciA9IGRhcmtfdGV4dCksCiAgICAgIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gYmFzZV9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sb3VyID0gbWlkX3RleHQpLAogICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IHVuaXQoYygzLCAwLCAwLCAwKSwgIm1tIikpLAogICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGJhc2Vfc2l6ZSAqIDEuMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcmdpbiA9IHVuaXQoYygwLCA1LCAwLCAwKSwgIm1tIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYW5nbGUgPSA5MCksCiAgICAgIGxlZ2VuZC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemU9YmFzZV9zaXplICogMC45KSwKICAgICAgbGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBiYXNlX3NpemUgKiAwLjksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFjZSA9ICJib2xkIiksCiAgICAgIHBsb3QubWFyZ2luID0gbWFyZ2luKDAuMjUsIDAuMjUsIDAuMjUsIDAuMjUsImNtIikKICAgICkKfQoKc2l0ZV9jb2xzID0gYygiS2V5IExhcmdvIiA9ICJpbmRpYW5yZWQ0IiwgCiAgICAgICAgICAgICAgIk1hbmF0ZWUgUml2ZXIiID0gImNvcmFsIiwgCiAgICAgICAgICAgICAgIkZ0LiBIYW1lciIgPSAiY29yYWwzIiwKICAgICAgICAgICAgICAiVHlsZXIgQ292ZSIgPSAiZ29sZGVucm9kMSIsCiAgICAgICAgICAgICAgIkdhbmV5J3MgV2hhcmYiID0gImRhcmtnb2xkZW5yb2QzIiwgCiAgICAgICAgICAgICAgIkVza2VyIFBvaW50IiA9ICJkYXJrc2VhZ3JlZW4zIiwKICAgICAgICAgICAgICAiU2F3eWVyIFBhcmsiID0gInBhbGVncmVlbjQiLCAKICAgICAgICAgICAgICAiU3QuIFRob21hcyBkZSBLZW50IFdoYXJmIiA9ICJzdGVlbGJsdWUyIiwKICAgICAgICAgICAgICAiUml0Y2hpZSBXaGFyZiIgPSAic3RlZWxibHVlNCIpCmBgYAoKIyMgU2l0ZSBDaGFyYWN0ZXJpc3RpY3MKCmBgYHtyfQpzaXRlX3RlbXBzID0gZnVsbF9kYXRhICU+JSAKICBkcGx5cjo6c2VsZWN0KHNpdGUsIGxhdCwgc2Vhc29uLCBkb3ksIGNvbGxlY3Rpb25fdGVtcCwgY29sbGVjdGlvbl9zYWxpbml0eSkgJT4lICAKICBkaXN0aW5jdCgpICU+JSAKICBmaWx0ZXIoZG95ID4gMTAwKSAKYGBgCgpDb3BlcG9kcyB3ZXJlIGNvbGxlY3RlZCBieSBzdXJmYWNlIHRvdyBmcm9tIHNpdGVzIGFjcm9zcyB0aGUgV2VzdGVybiBBdGxhbnRpYyBhdCBzZXZlcmFsIHRpbWVzIHRocm91Z2hvdXQgdGhlIHllYXIuIFRoZSBzaXRlcyBhcmUgc2hvd24gYmVsb3cuIFRlbXBlcmF0dXJlcyBhdCB0aGUgdGltZSBvZiBjb2xsZWN0aW9uIHdlcmUgbWVhc3VyZWQgdXNpbmcgYSBtYW51YWwgdGhlcm1vbWV0ZXIuIEFjcm9zcyB0aGUgZW50aXJlIHNldCBvZiBjb2xsZWN0aW9ucywgdGVtcGVyYXR1cmUgcmFuZ2VkIGZyb20gYHIgbWluKHNpdGVfdGVtcHMkY29sbGVjdGlvbl90ZW1wKWDCsEMgdG8gYHIgbWF4KHNpdGVfdGVtcHMkY29sbGVjdGlvbl90ZW1wKWDCsEMuCgpgYGB7ciBzaXRlLWNoYXJzLCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9Nn0KY29vcmRzID0gc2l0ZV9kYXRhICU+JQogIGRwbHlyOjpzZWxlY3Qoc2l0ZSwgbG9uZywgbGF0KSAlPiUKICBkaXN0aW5jdCgpCgpzaXRlX21hcCA9IG1hcF9kYXRhKCJ3b3JsZCIpICU+JSAKICBmaWx0ZXIocmVnaW9uICVpbiUgYygiVVNBIiwgIkNhbmFkYSIpKSAlPiUgCiAgZ2dwbG90KCkgKyAKICBnZW9tX3BvbHlnb24oYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IGdyb3VwKSwKICAgICAgICAgICAgICAgZmlsbCA9ICJsaWdodGdyZXkiKSArIAogIGNvb3JkX21hcCh4bGltID0gYygtODUsLTYwKSwKICAgICAgICAgICAgeWxpbSA9IGMoMjUsIDQ4KSkgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBjb29yZHMsCiAgICAgICAgICAgICBtYXBwaW5nID0gYWVzKHggPSBsb25nLCB5ID0gbGF0LCBjb2xvdXIgPSBzaXRlKSwKICAgICAgICAgICAgIHNpemUgPSAzKSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh4ID0gIkxvbmdpdHVkZSIsIAogICAgICAgeSA9ICJMYXRpdHVkZSIpICsgCiAgdGhlbWVfbWF0dChiYXNlX3NpemUgPSAxNikKCnNpdGVfdGVtcF9wbG90ID0gZ2dwbG90KHNpdGVfdGVtcHMsIGFlcyh4ID0gZG95LCB5ID0gY29sbGVjdGlvbl90ZW1wLCBjb2xvdXIgPSBzaXRlKSkgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMikgKyAKICBnZW9tX3BvaW50KHNpemUgPSA1KSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIlRlbXBlcmF0dXJlICjCsEMpIiwKICAgICAgIHggPSAiRGF5IG9mIHRoZSBZZWFyIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2Uoc2l0ZV9tYXAsIHNpdGVfdGVtcF9wbG90LCBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gImJvdHRvbSIpCmBgYAoKQ29sbGVjdGlvbnMgYWltZWQgdG8gb2J0YWluIGNvcGVwb2RzIG5lYXIgdGhlIG9uc2V0IG9mIHBlYWsgdGVtcGVyYXR1cmVzLCBhZnRlciBwZWFrIHRlbXBlcmF0dXJlcywgYW5kIHRoZW4gYXQgbG93IHRlbXBlcmF0dXJlcy4gUmVnaW9uYWwgZGF0YSBpcyBub3QgYXZhaWxhYmxlIGZvciBhbGwgc2l0ZXMsIHNvIGhlcmUgd2UndmUgcGllY2VkIHRvZ2V0aGVyIGRhaWx5IHRlbXBlcmF0dXJlIHZhbHVlcyBmcm9tIGVpdGhlciBsb2NhbCB0ZW1wZXJhdHVyZSBzZW5zb3JzIChzaXRlcyBpbiBGbG9yaWRhIGFuZCB0aGUgQ2hlc2FwZWFrZSkgYW5kIGhpZ2ggcmVzb2x1dGlvbiBzYXRlbGxpdGUgdGVtcGVyYXR1cmUgZGF0YSAoQ29ubmVjdGljdXQsIE1haW5lLCBhbmQgdGhlIENhbmFkaWFuIHNpdGVzKS4gVGhpcyBzYXRlbGxpdGUgZGF0YSBjb21lcyBmcm9tIHRoZSBOT0FBIDEvNMKwIERhaWx5IE9wdGltdW0gSW50ZXJwb2xhdGlvbiBTZWEgU3VyZmFjZSBUZW1wZXJhdHVyZSAoT0lTU1QpLiAKClRoZXNlIHRlbXBlcmF0dXJlIHByb2ZpbGVzIGFyZSBzaG93biBiZWxvdywgd2l0aCB0aGUgdGVtcGVyYXR1cmVzIG1lYXN1cmVkIGR1cmluZyB0aGUgdGltZSBvZiBjb2xsZWN0aW9uIGluY2x1ZGVkIGZvciBjb21wYXJpc29uIEluIHNldmVyYWwgY2FzZXMgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSBkb2VzIG5vdCBtYXRjaCB0aGUgcmVjb3JkZWQgZGFpbHkgYXZlcmFnZXMsIGJ1dCB0aGUgdGVtcGVyYXR1cmUgcmVjb3JkcyBkbyBnaXZlIGEgZ2VuZXJhbCBzZW5zZSBvZiB0aGUgdGltaW5nIG9mIHNlYXNvbmFsIG1heGltYS4gSW4gZ2VuZXJhbCwgdGhlIGZpcnN0IHNhbXBsZSBmcm9tIGVhY2ggc2l0ZSBmZWxsIGp1c3QgYWZ0ZXIgdGhlIHNpdGUgcmVhY2hlZCB0aGUgd2FybWVzdCBwZXJpb2QuIFRoZSBleGNlcHRpb24gdG8gdGhhdCBwYXR0ZXJuIGlzIGluIEZsb3JpZGEsIHdoZXJlIGNvbGxlY3Rpb25zIG9jY3VycmVkIGFmdGVyIGFuIGV4dGVuZGVkIHBlcmlvZCBvZiBoaWdoIHRlbXBlcmF0dXJlcy4gCgpgYGB7ciBjb250aW51b3VzLXRlbXBzLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02fQp0ZW1wX3Byb2ZpbGVzID0gdGVtcF9wcm9maWxlcyAlPiUgCiAgZmlsdGVyKGRveSA+IDEwMCkgJT4lIAogIG11dGF0ZShyZWdpb24gPSBmY3RfcmVsZXZlbChyZWdpb24sICJGbG9yaWRhIiwgIkNoZXNhcGVha2UiLCAiQ29ubmVjdGljdXQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTWFpbmUiLCAiU2hlZGlhYyIsICJNaXJhbWljaGkiKSkKCnNpdGVfdGVtcHMyID0gc2l0ZV90ZW1wcyAlPiUgCiAgbXV0YXRlKHJlZ2lvbiA9IGNhc2Vfd2hlbigKICAgIHNpdGUgPT0gIk1hbmF0ZWUgUml2ZXIiIH4gIkZsb3JpZGEiLAogICAgc2l0ZSA9PSAiRnQuIEhhbWVyIiB+ICJGbG9yaWRhIiwKICAgIHNpdGUgPT0gIlR5bGVyIENvdmUiIH4gIkNoZXNhcGVha2UiLAogICAgc2l0ZSA9PSAiR2FuZXkncyBXaGFyZiIgfiAiQ2hlc2FwZWFrZSIsCiAgICBzaXRlID09ICJFc2tlciBQb2ludCIgfiAiQ29ubmVjdGljdXQiLAogICAgc2l0ZSA9PSAiU2F3eWVyIFBhcmsiIH4gIk1haW5lIiwKICAgIHNpdGUgPT0gIlN0LiBUaG9tYXMgZGUgS2VudCBXaGFyZiIgfiAiU2hlZGlhYyIsCiAgICBzaXRlID09ICJSaXRjaGllIFdoYXJmIiB+ICJNaXJhbWljaGkiKSwKICAgIHJlZ2lvbiA9IGZjdF9yZWxldmVsKHJlZ2lvbiwgIkZsb3JpZGEiLCAiQ2hlc2FwZWFrZSIsICJDb25uZWN0aWN1dCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAiTWFpbmUiLCAiU2hlZGlhYyIsICJNaXJhbWljaGkiKSkKCmdncGxvdCh0ZW1wX3Byb2ZpbGVzLCBhZXMoeCA9IGRveSwgeSA9IHRlbXBfYykpICsgCiAgZmFjZXRfd3JhcChyZWdpb25+LikgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBzaXRlX3RlbXBzMiwKICAgICAgICAgICAgIGFlcyh4ID0gZG95LCB5ID0gY29sbGVjdGlvbl90ZW1wLCBjb2xvdXIgPSBzaXRlKSwKICAgICAgICAgICAgIHNpemUgPSAzKSArCiAgZ2VvbV9saW5lKCkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHggPSAiRGF5IG9mIHRoZSBZZWFyIiwgCiAgICAgICB5ID0gIk1lYW4gRGFpbHkgVGVtcC4gKMKwQykiKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIAogICAgICAgIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMzIwLCBoanVzdCA9IDAsIHZqdXN0ID0gMC41KSkKYGBgCgoKRXhhY3QgbG9jYXRpb25zIGZvciB0aGUgc2l0ZXMgYXJlIHByb3ZpZGVkIGhlcmUuIAoKYGBge3Igc2l0ZS10YWJsZX0Kc2l0ZV9kYXRhICU+JSAgCiAgYXJyYW5nZShsYXQpICU+JSAgCiAgc2VsZWN0KCJTaXRlIiA9IHNpdGUsICJSZWdpb24iID0gcmVnaW9uLCAiTGF0IiA9IGxhdCwgIkxvbmciID0gbG9uZykgJT4lIAogIGtuaXRyOjprYWJsZShhbGlnbiA9ICJjIikKYGBgCgpOZXN0ZWQgd2l0aGluIGVhY2ggb2YgdGhlIHRocmVlIHJlZ2lvbnMgKFNvdXRoLCBDZW50cmFsLCBhbmQgTm9ydGhlcm4gcmVnaW9ucykgYXJlIHBhaXJzIG9mIGxvdyBhbmQgaGlnaCBzYWxpbml0eSBzaXRlczogICAgCgpgYGB7ciBzYWwtdGFibGV9CmRhdGEuZnJhbWUoIlJlZ2lvbiIgPSBjKCJTb3V0aCIsICJDZW50cmFsIiwgIk5vcnRoIiksCiAgICAgICAgICAgIkxvdyBTYWxpbml0eSIgPSBjKCJGdC4gSGFtZXIiLCAiR2FuZXkncyBXaGFyZiIsICJSaXRjaGllIFdoYXJmIiksCiAgICAgICAgICAgIkhpZ2ggU2FsaW5pdHkiID0gYygiTWFuYXRlZSBSaXZlciIsICJUeWxlciBDb3ZlIiwgIlN0LiBUaG9tYXMgZGUgS2VudCBXaGFyZiIpKSAlPiUgCiAga25pdHI6OmthYmxlKGFsaWduID0gImMiKQpgYGAKClwgCgpUaGVyZSBhcmUgZmFpcmx5IHdlbGwtZXN0YWJsaXNoZWQgZGl2ZXJnZW5jZXMgYmV0d2VlbiBoaWdoIHNhbGluaXR5IGFuZCBsb3cgc2FsaW5pdHkgcG9wdWxhdGlvbnMgb2YgKkFjYXJ0aWEgdG9uc2EqLiBUaGVzZSBzZXRzIG9mIGdlb2dyYXBoaWNhbGx5IHByb3hpbWF0ZSBidXQgaXNvbGF0ZWQgcG9wdWxhdGlvbnMgcHJvdmlkZSBpbmRlcGVuZGVudCBjb21wYXJpc29ucyBvZiB0aGUgZWZmZWN0cyBvZiBzZWFzb25hbGl0eS4gU2hvd24gaGVyZSBhcmUgdGhlIGNvbGxlY3Rpb24gY29uZGl0aW9ucyBmb3IgdGhlc2UgcGFpcnMgb2Ygc2l0ZXMuIFRlbXBlcmF0dXJlIHdhcyB0eXBpY2FsbHkgc2ltaWxhciBhY3Jvc3MgdGhlIHBhaXJzIHdpdGhpbiBlYWNoIGNvbGxlY3Rpb24sIHdoaWxlIHNhbGluaXR5IGRpZmZlcmVuY2VzIHdlcmUgZmFpcmx5IHN0YWJsZSBhY3Jvc3MgY29sbGVjdGlvbnMuIAoKYGBge3Igc2Vhc29uLXNhbC1jb21wcywgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9OH0Kc2Vhc29uX2NvbHMgPSBjKCJlYXJseSIgPSAiZ3JleTc1IiwgCiAgICAgICAgICAgICAgICAicGVhayIgPSAiZ3JleTUwIiwgCiAgICAgICAgICAgICAgICAibGF0ZSIgPSAiZ3JleTI1IikKCnNhbF9yZWdpb25zID0gZGF0YS5mcmFtZShyZWdpb24gPSByZXAoYygiU291dGgiLCAiQ2VudHJhbCIsICJOb3J0aCIpLCBlYWNoID0gMiksIAogICAgICAgICAgICAgICAgICAgICAgICAgc2l0ZSA9IGMoIkZ0LiBIYW1lciIsICJNYW5hdGVlIFJpdmVyIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiR2FuZXkncyBXaGFyZiIsICJUeWxlciBDb3ZlIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUml0Y2hpZSBXaGFyZiIsICJTdC4gVGhvbWFzIGRlIEtlbnQgV2hhcmYiKSwKICAgICAgICAgICAgICAgICAgICAgICAgIHNhbGluaXR5ID0gYygibG93IiwgImhpZ2giKSkKCnNhbF9jb21wcyA9IGZ1bGxfZGF0YSAlPiUgCiAgZmlsdGVyKHNpdGUgJWluJSBzYWxfcmVnaW9ucyRzaXRlKSAlPiUgCiAgaW5uZXJfam9pbihzYWxfcmVnaW9ucywgYnkgPSBjKCJzaXRlIikpICU+JSAKICBzZWxlY3QoIHJlZ2lvbiA9IHJlZ2lvbi55LCBzaXRlLCBzYWxpbml0eSwgc2Vhc29uLCBkb3ksIGNvbGxlY3Rpb25fdGVtcCwgY29sbGVjdGlvbl9zYWxpbml0eSwKICAgICAgICAgIHNpemUsIGN0bWF4LCB3YXJtaW5nX3RvbCkgJT4lIAogIG11dGF0ZShzYWxpbml0eSA9IGZjdF9yZWxldmVsKHNhbGluaXR5LCAibG93IiwgImhpZ2giKSwKICAgICAgICAgcmVnaW9uID0gZmN0X3JlbGV2ZWwocmVnaW9uLCAiU291dGgiLCAiQ2VudHJhbCIsICJOb3J0aCIpKQoKc2FsX2NvbXBfdGVtcHMgPSBzYWxfY29tcHMgJT4lICAKICBzZWxlY3Qoc2FsaW5pdHksIHNlYXNvbiwgcmVnaW9uLCBjb2xsZWN0aW9uX3RlbXAsIGNvbGxlY3Rpb25fc2FsaW5pdHkpICU+JSAKICBkaXN0aW5jdCgpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzYWxpbml0eSwgeSA9IGNvbGxlY3Rpb25fdGVtcCwgY29sb3VyID0gc2Vhc29uLCBncm91cCA9IHNlYXNvbikpICsgCiAgZmFjZXRfd3JhcChyZWdpb25+LikgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMS41KSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDQpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzZWFzb25fY29scykgKyAKICBsYWJzKHkgPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIsCiAgICAgICB4ID0gIiIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoYmFzZV9zaXplID0gMTQpCgpzYWxfY29tcF9zYWwgPSBzYWxfY29tcHMgJT4lICAKICBzZWxlY3Qoc2FsaW5pdHksIHNlYXNvbiwgcmVnaW9uLCBjb2xsZWN0aW9uX3RlbXAsIGNvbGxlY3Rpb25fc2FsaW5pdHkpICU+JSAKICBkaXN0aW5jdCgpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzYWxpbml0eSwgeSA9IGNvbGxlY3Rpb25fc2FsaW5pdHksIGNvbG91ciA9IHNlYXNvbiwgZ3JvdXAgPSBzZWFzb24pKSArIAogIGZhY2V0X3dyYXAocmVnaW9ufi4pICsgCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDEuNSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2Vhc29uX2NvbHMpICsgCiAgbGFicyh5ID0gIkNvbGxlY3Rpb24gU2FsaW5pdHkgKHBzdSkiLAogICAgICAgeCA9ICJTYWxpbml0eSIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoYmFzZV9zaXplID0gMTQpCgpnZ2FycmFuZ2Uoc2FsX2NvbXBfdGVtcHMsIHNhbF9jb21wX3NhbCwgbnJvdyA9IDIsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAicmlnaHQiKQpgYGAKClRoZSBsYXRpdHVkaW5hbCBncmFkaWVudCBjb3ZlcnMgYSB3aWRlIHJhbmdlIG9mIHNlYXNvbmFsaXR5LiBTaG93biBiZWxvdyBpcyB0aGUgdGVtcGVyYXR1cmUgcmFuZ2UuIFdoaWxlIGJhc2VkIG9uIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmVzLCBhbmQgdGhlcmVmb3JlIGFuIHVuZGVyZXN0aW1hdGUgb2YgdGhlIHRvdGFsIHNlYXNvbmFsIHJhbmdlIG9mIHRlbXBlcmF0dXJlcywgdGhlc2UgcGF0dGVybnMgYXJlIHJlcHJlc2VudGF0aXZlIG9mIHRoZSBleHBlY3RlZCBsYXRpdHVkaW5hbCBncmFkaWVudCBpbiBzZWFzb25hbGl0eS4gCgpgYGB7ciBsYXQtdGVtcC1yYW5nZS1wbG90LCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD01fQpzaXRlX3RlbXBzICU+JSAKICBncm91cF9ieShzaXRlLCBsYXQpICU+JSAgCiAgc3VtbWFyaXNlKHRlbXBfcmFuZ2UgPSBtYXgoY29sbGVjdGlvbl90ZW1wKSAtIG1pbihjb2xsZWN0aW9uX3RlbXApKSAlPiUgIAogIGdncGxvdChhZXMoeCA9IGxhdCwgeSA9IHRlbXBfcmFuZ2UpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IHNpdGUpLAogICAgICAgICAgICAgc2l6ZSA9IDMpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHggPSAiTGF0aXR1ZGUiLCAKICAgICAgIHkgPSAiQ29sbGVjdGlvbiBUZW1wLiBSYW5nZSAowrBDKSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgoKIyMgUGhlbm90eXBpYyBNZWFzdXJlbWVudHMgCgojIyMgQ3JpdGljYWwgVGhlcm1hbCBMaW1pdHMKCkEgdG90YWwgb2YgYHIgZGltKGFsbF9kYXRhKVsxXWAgaW5kaXZpZHVhbHMgd2VyZSBleGFtaW5lZC4gQ3JpdGljYWwgdGhlcm1hbCBsaW1pdHMgYW5kIGJvZHkgc2l6ZSBtZWFzdXJlbWVudHMgd2VyZSBtYWRlIGJlZm9yZSBpbmRpdmlkdWFscyB3ZXJlIHByZXNlcnZlZCBpbiBldGhhbm9sLiBXZSBleGNsdWRlZCBkYXRhIGZvciBgciBkaW0oZXhjbHVkZWQpWzFdYCBpbmRpdmlkdWFscywgZGV0YWlsZWQgYmVsb3cuIFRoZXNlIGluZGl2aWR1YWxzIGhhZCBlaXRoZXIgdmVyeSBsb3cgQ1RtYXggb3Igd2VyZSwgdXBvbiByZS1leGFtaW5hdGlvbiBvZiBwaG90b2dyYXBocywgaWRlbnRpZmllZCBhcyBqdXZlbmlsZXMgaW5zdGVhZCBvZiBtYXR1cmUgZmVtYWxlcy4gV2l0aCB0aGVzZSBpbmRpdmlkdWFscyBleGNsdWRlZCwgKip0aGUgZnVsbCBkYXRhIHNldCBjb250YWlucyBgciBkaW0oZnVsbF9kYXRhKVsxXWAgcGhlbm90eXBlZCBpbmRpdmlkdWFscyoqLiAgIAoKYGBge3IgZXhjbHVkZWQtaW5kc30KZXhjbHVkZWQgJT4lIAogIHNlbGVjdChyZWdpb24sIHNpdGUsIHNlYXNvbiwgY29sbGVjdGlvbl90ZW1wLCBjb2xsZWN0aW9uX3NhbGluaXR5LCByZXBsaWNhdGUsIHR1YmUsIGN0bWF4LCBzaXplKSAlPiUgCiAga25pdHI6OmthYmxlKGFsaWduID0gImMiKQpgYGAKCkNyaXRpY2FsIHRoZXJtYWwgbWF4aW1hIChDVG1heCkgd2FzIG1lYXN1cmVkIHVzaW5nIGEgY3VzdG9tIHNldHVwLiBUaGUgbWV0aG9kIHVzZXMgYSBzdGFuZGFyZCBkeW5hbWljIHJhbXBpbmcgYXNzYXkgdG8gZGV0ZXJtaW5lIHRoZSBtYXhpbXVtIHRlbXBlcmF0dXJlIGluZGl2aWR1YWxzIGNvdWxkIHN1c3RhaW4gbm9ybWFsIGZ1bmN0aW9uaW5nLiBUaGlzIGRpZmZlcnMgZnJvbSBsZXRoYWwgdGVtcGVyYXR1cmVzLCBhbmQgaW5kZWVkLCBhbGwgaW5kaXZpZHVhbHMgb2JzZXJ2ZWQgc28gZmFyIHJlY292ZXJlZCBmb2xsb3dpbmcgdGhlIGFzc2F5LgoKSW5kaXZpZHVhbHMgd2VyZSByZXN0ZWQgZm9yIG9uZSBob3VyIGFmdGVyIGNvbGxlY3Rpb24gYmVmb3JlIHRoZSBhc3NheS4gRHVyaW5nIHRoZSBhc3NheSwgY29wZXBvZHMgd2VyZSBoZWxkIGluIGFydGlmaWNpYWwgc2Vhd2F0ZXIsIGNvbXBvc2VkIG9mIGJvdHRsZWQgc3ByaW5nIHdhdGVyIGFuZCBJbnN0YW50IE9jZWFuIHNhbHQgbWl4IGFkanVzdGVkIHRvIG1hdGNoIGNvbGxlY3Rpb24gc2FsaW5pdGllcy4gRHVyaW5nIHRoZSBhc3NheSwgc2V2ZXJhbCAnY29udHJvbCcgaW5kaXZpZHVhbHMgd2VyZSBtYWludGFpbmVkIGluIHRoaXMgc29sdXRpb24gYXQgYW1iaWVudCB0ZW1wZXJhdHVyZXMgd2l0aG91dCB0aGUgdGVtcGVyYXR1cmUgcmFtcCB0byBlbnN1cmUgdGhhdCB0aGVyZSB3YXMgbm8gYmFja2dyb3VuZCBtb3J0YWxpdHkuIFdoZW4gc29ydGluZyBpbmRpdmlkdWFscyBmcm9tIHRoZSBwbGFua3RvbiB0b3cgY29udGVudHMsIHRoZXkgd2VyZSBoZWxkIGluIGEgNTA6NTAgbWl4IG9mIDYwIHVtIGZpbHRlcmVkIHdhdGVyIGZyb20gdGhlIGNvbGxlY3Rpb24gc2l0ZSBhbmQgYXJ0aWZpY2lhbCBzZWF3YXRlciBhcyBhbiBhZGRpdGlvbmFsIGFjY2xpbWF0aW9uIHN0ZXAuIAoKU2FtcGxlIHNpemVzIHZhcmllZCBzbGlnaHRseSBhY3Jvc3MgZXhwZXJpbWVudHMsIGJ1dCBtb3N0IHNpdGVzIGhhZCAyMCBpbmRpdmlkdWFscyBtZWFzdXJlZCBwZXIgc2Vhc29uLiBUaGUgbWFqb3IgZXhjZXB0aW9ucyB3ZXJlIHRoZSBlYXJseSBzYW1wbGVzIGZyb20gdGhlIEZsb3JpZGEgc2l0ZXMgYW5kIHRoZSBsYXRlIHNhbXBsZSBmcm9tIFNhd3llciBQYXJrIChNYWluZSkuIE9ubHkgdHdvIHNldHMgb2Ygc2FtcGxlcyAocGVhayBhbmQgbGF0ZSkgd2VyZSBjb2xsZWN0ZWQgZnJvbSBGb3J0IEhhbWVyIGFuZCBNYW5hdGVlIFJpdmVyLiBObyBzYW1wbGVzIHdlcmUgY29sbGVjdGVkIGZyb20gS2V5IExhcmdvIGZvciB0aGlzIHByb2plY3QsIGFzICpBY2FydGlhIHRvbnNhKiB3YXNuJ3QgcHJlc2VudCBpbiB0aGUgd2F0ZXIgZHVyaW5nIHRoZSBwZWFrIHNlYXNvbiwgbGlrZWx5IGR1ZSB0byB0aGUgcmVjZW50IGV4dHJlbWUgaGVhdCBldmVudC4gVGhlIGxhdGUgc2Vhc29uIGNvbGxlY3Rpb24gZnJvbSBTYXd5ZXIgUGFyayBvY2N1cnJlZCBhZnRlciAqQWNhcnRpYSB0b25zYSogYWJ1bmRhbmNlIGRlY3JlYXNlZC4gU2FtcGxlcyBmcm9tIHRoaXMgcGVyaW9kIHdlcmUgZG9taW5hdGVkIGJ5ICpBY2FydGlhIGh1ZHNvbmljYSogaW5zdGVhZC4gCgpgYGB7ciBzYW1wbGUtc2l6ZS1wbG90LCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9NX0KZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBzaXRlLCBmaWxsID0gc2l0ZSkpICsgCiAgZmFjZXRfd3JhcChzZWFzb25+LikgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBjKDAsMjApLAogICAgICAgICAgICAgY29sb3VyID0gImdyZXk3MCIpICsgCiAgZ2VvbV9iYXIoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBjb29yZF9mbGlwKCkgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBwYW5lbC5ib3JkZXIgPSBlbGVtZW50X3JlY3QobGluZXdpZHRoID0gMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbCA9IE5BKSwKICAgICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KHNpemUgPSAyMCksCiAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF9ibGFuaygpKQpgYGAKClNob3duIGJlbG93IGFyZSB0aGUgbWVhc3VyZWQgQ1RtYXggdmFsdWVzLiBOb3RlOiBDVG1heCB2YWx1ZXMgZm9yIHRoZSBlYXJseSBzZWFzb24gS2V5IExhcmdvIGNvcGVwb2RzIHdlcmUgY29sbGVjdGVkIGF0IHRoZSBlbmQgb2YgRmVicnVhcnkgMjAyMyBhcyBwYXJ0IG9mIGEgc2VwYXJhdGUgcHJvamVjdC4gQm9keSBzaXplIHZhbHVlcyB3ZXJlIG5vdCBtZWFzdXJlZCBkdXJpbmcgdGhpcyBwcm9qZWN0LCBub3Igd2VyZSBjb3BlcG9kcyBpbmRpdmlkdWFsbHkgcHJlc2VydmVkIGFmdGVyIHRoZSBleHBlcmltZW50cy4gVGhlc2UgZWFybHkgc2Vhc29uIENUbWF4IHZhbHVlcyBhcmUgaW5jbHVkZWQgYXMgYSBwb2ludCBvZiBjb21wYXJpc29uLiBJbmRpdmlkdWFsIG1lYXN1cmVtZW50cyBhcmUgc2hvd24gaW4gc21hbGwgcG9pbnRzIGZvciBlYWNoIGNvbGxlY3Rpb24uIFRoZSBsYXJnZSBwb2ludHMgaW5kaWNhdGUgdGhlIG1lYW4gdmFsdWVzIGZvciBlYWNoIGNvbGxlY3Rpb24uIAoKYGBge3Igc2Vhc29uYWwtY3QtbWF4fQptZWFuX2N0bWF4ID0gZnVsbF9kYXRhICU+JSAKICBncm91cF9ieShzaXRlLCBzZWFzb24sIGRveSwgY29sbGVjdGlvbl90ZW1wKSAlPiUgCiAgc3VtbWFyaXplKG1lYW5fY3RtYXggPSBtZWFuKGN0bWF4KSwKICAgICAgICAgICAgbWVkaWFuX2N0bWF4ID0gbWVkaWFuKGN0bWF4KSkKCmN0bWF4X3Bsb3QgPSBnZ3Bsb3QoZnVsbF9kYXRhLCBhZXMoeCA9IHNlYXNvbiwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzaXRlKSkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IG1lYW5fY3RtYXgsIAogICAgICAgICAgICBhZXMoeSA9IG1lYW5fY3RtYXgsIGdyb3VwID0gc2l0ZSksCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjQpLAogICAgICAgICAgICBsaW5ld2lkdGggPSAxKSArIAogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXJkb2RnZShqaXR0ZXIud2lkdGggPSAwLjEsIGppdHRlci5oZWlnaHQgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2RnZS53aWR0aCA9IDAuNCksCiAgICAgICAgICAgICBhbHBoYSA9IDAuMykgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBtZWFuX2N0bWF4LCAKICAgICAgICAgICAgIGFlcyh5ID0gbWVhbl9jdG1heCksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgIHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICB4ID0gIlNlYXNvbiIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKCmN0bWF4X3Bsb3QKYGBgCgpgYGB7ciBkb3ktY3QtbWF4LCBpbmNsdWRlID0gRn0KIyBUaGUgc2FtZSBkYXRhIGlzIHNob3duIGJlbG93LCBwbG90dGVkIGFnYWluc3QgZGF5IG9mIHRoZSB5ZWFyIGluc3RlYWQgb2Ygc2Vhc29uLiBUaGlzIGFjY291bnRzIGZvciB0aGUgdmFyaWFibGUgdGltaW5nIG9mIGNvbGxlY3Rpb25zIGFjcm9zcyByZWdpb25zIChlLmcuIC0gdGhlIGNvbXByZXNzZWQgY29sbGVjdGlvbnMgZnJvbSB0aGUgTm9ydGhlcm4gc2l0ZXMgdG8gYWNjb21vZGF0ZSB0aGUgZWFybGllciBvbnNldCBvZiBjb2xkIHRlbXBlcmF0dXJlcykuIAoKZ2dwbG90KGZpbHRlcihmdWxsX2RhdGEsIHNpdGUgIT0gIktleSBMYXJnbyIpLCBhZXMoeCA9IGRveSwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzaXRlKSkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IGZpbHRlcihtZWFuX2N0bWF4LCBzaXRlICE9ICJLZXkgTGFyZ28iKSwgCiAgICAgICAgICAgIGFlcyh5ID0gbWVkaWFuX2N0bWF4LCBncm91cCA9IHNpdGUpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gCiAgICAgICAgICAgICAgIHBvc2l0aW9uX2ppdHRlcmRvZGdlKAogICAgICAgICAgICAgICAgIGppdHRlci53aWR0aCA9IDAuMSwgCiAgICAgICAgICAgICAgICAgaml0dGVyLmhlaWdodCA9IDAsCiAgICAgICAgICAgICAgICAgZG9kZ2Uud2lkdGggPSAwLjQpLAogICAgICAgICAgICAgYWxwaGEgPSAwLjMpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gZmlsdGVyKG1lYW5fY3RtYXgsIHNpdGUgIT0gIktleSBMYXJnbyIpLCAKICAgICAgICAgICAgIGFlcyh5ID0gbWVkaWFuX2N0bWF4KSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjQpLAogICAgICAgICAgICAgc2l6ZSA9IDQpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgeGxpbSgxODAsMzUwKSArIAogIGxhYnMoeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICB4ID0gIkRheSBvZiB0aGUgWWVhciIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgpgYGB7ciBjdG1heC1pbmQtcG9wcy1kb3ksIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTYsIGluY2x1ZGUgPSBGfQojIENUbWF4IGRhdGEgZm9yIGVhY2ggaW5kaXZpZHVhbCBzaXRlIGlzIHNob3duIGJlbG93LCBwbG90dGVkIGFnYWluc3QgZGF5IG9mIHRoZSB5ZWFyLiAKCmdncGxvdChmaWx0ZXIoZnVsbF9kYXRhLCBzaXRlICE9ICJLZXkgTGFyZ28iKSwgCiAgICAgICBhZXMoeCA9IGRveSwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzaXRlKSkgKyAKICBmYWNldF93cmFwKC5+c2l0ZSwgc2NhbGVzID0gImZyZWUiKSArIAogIGdlb21fbGluZShkYXRhID0gZmlsdGVyKG1lYW5fY3RtYXgsIHNpdGUgIT0gIktleSBMYXJnbyIpLCAKICAgICAgICAgICAgYWVzKHkgPSBtZWFuX2N0bWF4LCBncm91cCA9IHNpdGUpLAogICAgICAgICAgICBsaW5ld2lkdGggPSAzLCBhbHBoYSA9IDAuNSkgKyAKICBnZW9tX3BvaW50KGFscGhhID0gMC44KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCAowrBDKSIsCiAgICAgICB4ID0gIkRheSBvZiBZZWFyIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgCiAgICAgICAgbGVnZW5kLnRpdGxlLmFsaWduID0gMC4xMjUsCiAgICAgICAgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAzMjAsIGhqdXN0ID0gMCwgdmp1c3QgPSAwLjUpKQpgYGAKCmBgYHtyIGN0bWF4LWluZC1wb3BzLXNlYXNvbiwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NiwgaW5jbHVkZSA9IEZ9CmdncGxvdChmdWxsX2RhdGEsIGFlcyh4ID0gc2Vhc29uLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNpdGUpKSArIAogIGZhY2V0X3dyYXAoLn5zaXRlLCBzY2FsZXMgPSAiZnJlZV95IikgKyAKICBnZW9tX2xpbmUoZGF0YSA9IG1lYW5fY3RtYXgsIAogICAgICAgICAgICBhZXMoeSA9IG1lZGlhbl9jdG1heCwgZ3JvdXAgPSBzaXRlKSwKICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNCksCiAgICAgICAgICAgIGxpbmV3aWR0aCA9IDMsIGFscGhhID0gMC41KSArIAogIGdlb21fbGluZShkYXRhID0gbWVhbl9jdG1heCwgCiAgICAgICAgICAgIGFlcyh5ID0gY29sbGVjdGlvbl90ZW1wLCBncm91cCA9IHNpdGUpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgbGluZXdpZHRoID0gMiwKICAgICAgICAgICAgY29sb3VyID0gImdyZXkiKSArIAogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXJkb2RnZShqaXR0ZXIud2lkdGggPSAwLjEsIGppdHRlci5oZWlnaHQgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2RnZS53aWR0aCA9IDAuNCksCiAgICAgICAgICAgICBhbHBoYSA9IDAuOCkgKyAKICAjIGdlb21fcG9pbnQoZGF0YSA9IG1lYW5fY3RtYXgsIAogICMgICAgICAgICAgICBhZXMoeSA9IG1lZGlhbl9jdG1heCksCiAgIyAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjQpLAogICMgICAgICAgICAgICBzaXplID0gNCkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHkgPSAiQ1RtYXggKMKwQykiLAogICAgICAgeCA9ICJTZWFzb24iKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgojIyMgV2FybWluZyB0b2xlcmFuY2UKCldhcm1pbmcgdG9sZXJhbmNlICh0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZXJtYWwgbGltaXRzIGFuZCBlbnZpcm9ubWVudGFsIHRlbXBlcmF0dXJlcykgaXMgYSBjb21tb25seSB1c2VkIG1ldHJpYyBvZiBjbGltYXRlIHZ1bG5lcmFiaWxpdHkuIFdlIGNhbGN1bGF0ZWQgdGhpcyBhcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIG1lYXN1cmVkIENUbWF4IHZhbHVlcyBhbmQgdGhlIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUuIFNtYWxsZXIgd2FybWluZyB0b2xlcmFuY2UgdmFsdWVzIGluZGljYXRlIHRoYXQgcG9wdWxhdGlvbnMgd2VyZSBuZWFyZXIgdG8gdGhlaXIgdXBwZXIgdGhlcm1hbCBsaW1pdHMsIGFuZCBtYXkgdGhlcmVmb3JlIGJlIG1vcmUgdnVsbmVyYWJsZSB0byBhZGRpdGlvbmFsIHdhcm1pbmcuIAoKYGBge3Igc2Vhc29uYWwtd2FybWluZy10b2x9Cm1lYW5fd3QgPSBmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHNpdGUsIHNlYXNvbikgJT4lIAogIHN1bW1hcml6ZShtZWFuX3d0ID0gbWVhbih3YXJtaW5nX3RvbCksCiAgICAgICAgICAgIG1lZGlhbl93dCA9IG1lZGlhbih3YXJtaW5nX3RvbCkpCgpnZ3Bsb3QoZnVsbF9kYXRhLCBhZXMoeCA9IHNlYXNvbiwgeSA9IHdhcm1pbmdfdG9sLCBjb2xvdXIgPSBzaXRlKSkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IG1lYW5fd3QsIAogICAgICAgICAgICBhZXMoeSA9IG1lYW5fd3QsIGdyb3VwID0gc2l0ZSksCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjQpLAogICAgICAgICAgICBsaW5ld2lkdGggPSAxKSArIAogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXJkb2RnZShqaXR0ZXIud2lkdGggPSAwLjEsIGppdHRlci5oZWlnaHQgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2RnZS53aWR0aCA9IDAuNCksCiAgICAgICAgICAgICBhbHBoYSA9IDAuMykgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBtZWFuX3d0LCAKICAgICAgICAgICAgIGFlcyh5ID0gbWVhbl93dCksCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgIHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJXYXJtaW5nIFRvbGVyYW5jZSAowrBDKSIsCiAgICAgICB4ID0gIlNlYXNvbiIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgojIyMgQm9keSBTaXplCgpGb2xsb3dpbmcgdGhlIENUbWF4IGFzc2F5LCBpbmRpdmlkdWFscyB3ZXJlIHBob3RvZ3JhcGhlZCBmb3IgYm9keSBzaXplIG1lYXN1cmVtZW50cy4gUHJvc29tZSBsZW5ndGhzIHdlcmUgbWVhc3VyZWQgZnJvbSB0aGVzZSBwaG90b2dyYXBocyB1c2luZyBhIHNjYWxlIG1pY3JvbWV0ZXIgYW5kIHRoZSBzb2Z0d2FyZSBJbWFnZUouIFRoZXNlIG1lYXN1cmVtZW50cyBhcmUgc2hvd24gYmVsb3cuIEFzIGJlZm9yZSwgbGFyZ2UgcG9pbnRzIGluZGljYXRlIHRoZSBtZWFuIGJvZHkgc2l6ZS4gV2hpbGUgbGVzcyBjb2hlc2l2ZSB0aGFuIENUbWF4LCBhIGdlbmVyYWwgdHJlbmQgb2YgaW5jcmVhc2luZyBib2R5IHNpemUgd2l0aCBsYXRpdHVkZSBhbmQgdGltZSBvZiB5ZWFyIGNhbiBiZSBzZWVuLiAKCmBgYHtyIHNlYXNvbmFsLWJvZHktc2l6ZX0KbWVhbl9zaXplID0gZnVsbF9kYXRhICU+JSAKICBncm91cF9ieShzaXRlLCBzZWFzb24sIGRveSwgY29sbGVjdGlvbl90ZW1wKSAlPiUgCiAgc3VtbWFyaXplKG1lYW5fc2l6ZSA9IG1lYW4oc2l6ZSksCiAgICAgICAgICAgIG1lZGlhbl9zaXplID0gbWVkaWFuKHNpemUpKQoKZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBzZWFzb24sIHkgPSBzaXplLCBjb2xvdXIgPSBzaXRlKSkgKyAKICBnZW9tX2xpbmUoZGF0YSA9IG1lYW5fc2l6ZSwgCiAgICAgICAgICAgIGFlcyh5ID0gbWVhbl9zaXplLCBncm91cCA9IHNpdGUpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgbGluZXdpZHRoID0gMSkgKyAKICBnZW9tX3BvaW50KHBvc2l0aW9uID0gcG9zaXRpb25faml0dGVyZG9kZ2Uoaml0dGVyLndpZHRoID0gMC4xLCBqaXR0ZXIuaGVpZ2h0ID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9kZ2Uud2lkdGggPSAwLjQpLAogICAgICAgICAgICAgYWxwaGEgPSAwLjMpICsgCiAgZ2VvbV9wb2ludChkYXRhID0gbWVhbl9zaXplLCAKICAgICAgICAgICAgIGFlcyh5ID0gbWVhbl9zaXplKSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjQpLAogICAgICAgICAgICAgc2l6ZSA9IDQpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIlByb3NvbWUgTGVuZ3RoIChtbSkiLAogICAgICAgeCA9ICJTZWFzb24iKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgCiAgICAgICAgbGVnZW5kLnRpdGxlLmFsaWduID0gMC4xMjUpCmBgYAoKYGBge3IgZG95LWJvZHktc2l6ZSwgaW5jbHVkZSA9IEZ9CmdncGxvdChkcm9wX25hKGZ1bGxfZGF0YSwgc2l6ZSksIGFlcyh4ID0gZG95LCB5ID0gc2l6ZSwgY29sb3VyID0gc2l0ZSkpICsgCiAgZ2VvbV9saW5lKGRhdGEgPSBkcm9wX25hKG1lYW5fc2l6ZSwgbWVhbl9zaXplKSwgCiAgICAgICAgICAgIGFlcyh5ID0gbWVkaWFuX3NpemUsIGdyb3VwID0gc2l0ZSksCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjQpLAogICAgICAgICAgICBsaW5ld2lkdGggPSAxKSArIAogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXJkb2RnZShqaXR0ZXIud2lkdGggPSAwLjEsIGppdHRlci5oZWlnaHQgPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2RnZS53aWR0aCA9IDAuNCksCiAgICAgICAgICAgICBhbHBoYSA9IDAuMykgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBkcm9wX25hKG1lYW5fc2l6ZSwgbWVhbl9zaXplKSwgCiAgICAgICAgICAgICBhZXMoeSA9IG1lZGlhbl9zaXplKSwKICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjQpLAogICAgICAgICAgICAgc2l6ZSA9IDQpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIlByb3NvbWUgTGVuZ3RoIChtbSkiLAogICAgICAgeCA9ICJEYXkgb2YgdGhlIFllYXIiKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgCiAgICAgICAgbGVnZW5kLnRpdGxlLmFsaWduID0gMC4xMjUpCmBgYAoKCmBgYHtyIHNpemUtaW5kLXBvcHMtZG95LCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02LCBpbmNsdWRlID0gRn0KIyBTaG93biBiZWxvdyBpcyB0aGUgYm9keSBzaXplIGRhdGEgZm9yIGVhY2ggaW5kaXZpZHVhbCBzaXRlLiAKCmdncGxvdChkcm9wX25hKGZ1bGxfZGF0YSwgc2l6ZSksIGFlcyh4ID0gZG95LCB5ID0gc2l6ZSwgY29sb3VyID0gc2l0ZSkpICsgCiAgZmFjZXRfd3JhcCgufnNpdGUpICsgCiAgZ2VvbV9saW5lKGRhdGEgPSBkcm9wX25hKG1lYW5fc2l6ZSwgbWVhbl9zaXplKSwgCiAgICAgICAgICAgIGFlcyh5ID0gbWVhbl9zaXplLCBncm91cCA9IHNpdGUpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgbGluZXdpZHRoID0gMywgYWxwaGEgPSAwLjUpICsgCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcmRvZGdlKGppdHRlci53aWR0aCA9IDAuMSwgaml0dGVyLmhlaWdodCA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvZGdlLndpZHRoID0gMC40KSwKICAgICAgICAgICAgIGFscGhhID0gMC44KSArIAogICMgZ2VvbV9wb2ludChkYXRhID0gbWVhbl9jdG1heCwgCiAgIyAgICAgICAgICAgIGFlcyh5ID0gbWVkaWFuX2N0bWF4KSwKICAjICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNCksCiAgIyAgICAgICAgICAgIHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJQcm9zb21lIExlbmd0aCAobW0pIiwKICAgICAgIHggPSAiRGF5IG9mIFllYXIiKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgpgYGB7ciBzaXplLWluZC1wb3BzLXNlYXNvbiwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NiwgaW5jbHVkZSA9IEZ9CmdncGxvdChmdWxsX2RhdGEsIGFlcyh4ID0gc2Vhc29uLCB5ID0gc2l6ZSwgY29sb3VyID0gc2l0ZSkpICsgCiAgZmFjZXRfd3JhcCgufnNpdGUpICsgCiAgZ2VvbV9saW5lKGRhdGEgPSBtZWFuX3NpemUsIAogICAgICAgICAgICBhZXMoeSA9IG1lZGlhbl9zaXplLCBncm91cCA9IHNpdGUpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC40KSwKICAgICAgICAgICAgbGluZXdpZHRoID0gMywgYWxwaGEgPSAwLjUpICsgCiAgZ2VvbV9wb2ludChwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcmRvZGdlKGppdHRlci53aWR0aCA9IDAuMSwgaml0dGVyLmhlaWdodCA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvZGdlLndpZHRoID0gMC40KSwKICAgICAgICAgICAgIGFscGhhID0gMC44KSArIAogICMgZ2VvbV9wb2ludChkYXRhID0gbWVhbl9jdG1heCwgCiAgIyAgICAgICAgICAgIGFlcyh5ID0gbWVkaWFuX2N0bWF4KSwKICAjICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNCksCiAgIyAgICAgICAgICAgIHNpemUgPSA0KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJQcm9zb21lIExlbmd0aCAobW0pIiwKICAgICAgIHggPSAiU2Vhc29uIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgCiAgICAgICAgbGVnZW5kLnRpdGxlLmFsaWduID0gMC4xMjUpCmBgYAoKIyMjIFNhbGluaXR5IFBhaXIgQ29tcGFyaXNvbnMgCgpUaGUgdGhyZWUgcGFpcnMgb2YgY3Jvc3Mtc2FsaW5pdHkgY29tcGFyaXNvbnMgZG8gc2hvdyBldmlkZW5jZSBmb3IgZmluZS1zY2FsZSB0cmFpdCBkaXZlcmdlbmNlLCBhbHRob3VnaCB0aGVyZSB3YXMgbm8gY29uc2lzdGVudCBwYXR0ZXJuIGluIHRoZSBkaXJlY3Rpb24gb3IgbWFnbml0dWRlIG9mIGRpZmZlcmVuY2VzLiBDVG1heCB3YXMgc2ltaWxhciBhY3Jvc3Mgc2l0ZXMgaW4gdGhlIFNvdXRoZXJuIGFuZCBDZW50cmFsIHBhaXJzLiBJbiB0aGUgTm9ydGhlcm4gcGFpciwgQ1RtYXggdGVuZGVkIHRvIGJlIHNsaWdodGx5IGxvd2VyIGZvciBpbmRpdmlkdWFscyBmcm9tIHRoZSBsb3cgc2FsaW5pdHkgc2l0ZS4gU2l6ZSB3YXMgbW9yZSB2YXJpYWJsZSBiZXR3ZWVuIHRoZSBwYWlyZWQgc2l0ZXMuIEluIHRoZSBTb3V0aCwgbG93IHNhbGluaXR5IGluZGl2aWR1YWxzIHdlcmUgY29uc2lzdGVudGx5IHNtYWxsZXIgdGhhbiBoaWdoIHNhbGluaXR5IGluZGl2aWR1YWxzLCBkZXNwaXRlIGV4cGVyaWVuY2luZyBzaW1pbGFyIHRlbXBlcmF0dXJlcy4gSW4gdGhlIENlbnRyYWwgcGFpciwgaW5kaXZpZHVhbHMgZnJvbSB0aGUgbG93IHNhbGluaXR5IHNpdGUgdGVuZGVkIHRvIGJlIHNsaWdodGx5IGxhcmdlciB0aGFuIHRob3NlIGZyb20gdGhlIGhpZ2ggc2FsaW5pdHkgc2l0ZSwgYWx0aG91Z2ggdGhpcyB2YXJpZWQgc2Vhc29uYWxseS4gU2l6ZXMgdGVuZGVkIHRvIGJlIG1vcmUgc2ltaWxhciBhY3Jvc3MgdGhlIGNvbGxlY3Rpb25zIGZyb20gdGhlIE5vcnRoZXJuIHBhaXIuIAoKYGBge3Igc2FsLXBhaXItdHJhaXRzfQpzYWxfY29tcF9jdG1heF9wbG90ID0gc2FsX2NvbXBzICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzYWxpbml0eSwgeSA9IGN0bWF4LCBjb2xvdXIgPSBzZWFzb24sIGdyb3VwID0gc2Vhc29uKSkgKyAKICBmYWNldF93cmFwKHJlZ2lvbn4uKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDIsCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC4yKSkgKyAKICAjZ2VvbV9saW5lKHNpemUgPSAxLjUpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzZWFzb25fY29scykgKyAKICBsYWJzKHkgPSAiQ1RtYXggKMKwQykiLAogICAgICAgeCA9ICIiKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKGJhc2Vfc2l6ZSA9IDE0KQoKc2FsX2NvbXBfc2l6ZV9wbG90ID0gc2FsX2NvbXBzICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzYWxpbml0eSwgeSA9IHNpemUsIGNvbG91ciA9IHNlYXNvbiwgZ3JvdXAgPSBzZWFzb24pKSArIAogIGZhY2V0X3dyYXAocmVnaW9ufi4pICsgCiAgZ2VvbV9wb2ludChzaXplID0gMiwgCiAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC4yKSkgKyAKICAjZ2VvbV9saW5lKHNpemUgPSAxLjUpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzZWFzb25fY29scykgKyAKICBsYWJzKHkgPSAiUHJvc29tZSBMZW5ndGggKG1tKSIsCiAgICAgICB4ID0gIiIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoYmFzZV9zaXplID0gMTQpCgpnZ2FycmFuZ2Uoc2FsX2NvbXBfY3RtYXhfcGxvdCwgc2FsX2NvbXBfc2l6ZV9wbG90LCBucm93ID0gMiwgY29tbW9uLmxlZ2VuZCA9IFQsIGxlZ2VuZCA9ICJyaWdodCIpCgojIyMKIyAKIyBzYWxfY29tcF9jdG1heC5tb2RlbCA9IGxtKGN0bWF4IH4gY29sbGVjdGlvbl90ZW1wLCBkYXRhID0gc2FsX2NvbXBzKQojICMgc3VtbWFyeShjdG1heF90ZW1wLm1vZGVsKQojICMgY2FyOjpBbm92YShjdG1heF90ZW1wLm1vZGVsKQojIHNhbF9jb21wX2N0bWF4X3Jlc2lkcyA9IHJlc2lkdWFscyhzYWxfY29tcF9jdG1heC5tb2RlbCkKIyAKIyBzYWxfY29tcF9zaXplLm1vZGVsID0gbG0oc2l6ZSB+IGNvbGxlY3Rpb25fdGVtcCwgZGF0YSA9IHNhbF9jb21wcykKIyAjIHN1bW1hcnkoc2l6ZV90ZW1wLm1vZGVsKQojICMgY2FyOjpBbm92YShzaXplX3RlbXAubW9kZWwpCiMgc2FsX2NvbXBfc2l6ZV9yZXNpZHMgPSByZXNpZHVhbHMoc2FsX2NvbXBfc2l6ZS5tb2RlbCkKIyAKIyBzYWxfY29tcF9jdG1heF9yZXNpZF9wbG90ID0gc2FsX2NvbXBzICU+JQojICAgbXV0YXRlKGN0bWF4X3Jlc2lkcyA9IHNhbF9jb21wX2N0bWF4X3Jlc2lkcywKIyAgICAgICAgICBzaXplX3Jlc2lkcyA9IHNhbF9jb21wX3NpemVfcmVzaWRzKSAlPiUKIyAgIGdncGxvdChhZXMoeCA9IHNhbGluaXR5LCB5ID0gY3RtYXhfcmVzaWRzLCBjb2xvdXIgPSBzZWFzb24sIGdyb3VwID0gc2Vhc29uKSkgKwojICAgZmFjZXRfd3JhcChyZWdpb25+LikgKwojICAgZ2VvbV9wb2ludChzaXplID0gMiwKIyAgICAgICAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IDAuNSkpICsKIyAgICNnZW9tX2xpbmUoc2l6ZSA9IDEuNSkgKwojICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzZWFzb25fY29scykgKwojICAgbGFicyh5ID0gIkNUbWF4IFxuUmVzaWR1YWxzIiwKIyAgICAgICAgeCA9ICIiKSArCiMgICB0aGVtZV9tYXR0X2ZhY2V0cyhiYXNlX3NpemUgPSAxNCkKIyAKIyBzYWxfY29tcF9zaXplX3Jlc2lkX3Bsb3QgPSBzYWxfY29tcHMgJT4lCiMgICBtdXRhdGUoY3RtYXhfcmVzaWRzID0gc2FsX2NvbXBfY3RtYXhfcmVzaWRzLAojICAgICAgICAgIHNpemVfcmVzaWRzID0gc2FsX2NvbXBfc2l6ZV9yZXNpZHMpICU+JQojICAgZ2dwbG90KGFlcyh4ID0gc2FsaW5pdHksIHkgPSBzaXplX3Jlc2lkcywgY29sb3VyID0gc2Vhc29uLCBncm91cCA9IHNlYXNvbikpICsKIyAgIGZhY2V0X3dyYXAocmVnaW9ufi4pICsKIyAgIGdlb21fcG9pbnQoc2l6ZSA9IDIsCiMgICAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAwLjUpKSArCiMgICAjZ2VvbV9saW5lKHNpemUgPSAxLjUpICsKIyAgIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2Vhc29uX2NvbHMpICsKIyAgIGxhYnMoeSA9ICJQcm9zb21lIExlbmd0aCBcblJlc2lkdWFscyIsCiMgICAgICAgIHggPSAiIikgKwojICAgdGhlbWVfbWF0dF9mYWNldHMoYmFzZV9zaXplID0gMTQpCiMgCiMgZ2dhcnJhbmdlKHNhbF9jb21wX2N0bWF4X3Jlc2lkX3Bsb3QsIHNhbF9jb21wX3NpemVfcmVzaWRfcGxvdCwgbnJvdyA9IDIsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAicmlnaHQiKQpgYGAKCiMjIFRyYWl0IENvcnJlbGF0aW9ucwoKUmVnYXJkbGVzcyBvZiB0aGUgdW5kZXJseWluZyBtZWNoYW5pc20gKGdlbmV0aWMgZGlmZmVyZW50aWF0aW9uIG9yIHBoZW5vdHlwaWMgcGxhc3RpY2l0eSksIHdlIGV4cGVjdCB0aGF0IGNvbGxlY3Rpb25zIGZyb20gd2FybWVyIHdhdGVycyBzaG91bGQgeWllbGQgY29wZXBvZHMgd2l0aCBoaWdoZXIgdGhlcm1hbCBsaW1pdHMgYW5kIHNtYWxsZXIgYm9keSBzaXplcy4gT3VyIG9ic2VydmF0aW9ucyBsYXJnZWx5IGZpdCB0aGlzIGV4cGVjdGF0aW9uLCB3aXRoIHN0cm9uZyBpbmNyZWFzZXMgaW4gQ1RtYXggYXQgaGlnaGVyIHRlbXBlcmF0dXJlcywgYW5kIGEgZ2VuZXJhbCBkZWNyZWFzZSBpbiBwcm9zb21lIGxlbmd0aHMgYXMgdGVtcGVyYXR1cmUgaW5jcmVhc2VkLiBUaGVyZSB3YXMgYSBsYXJnZXIgY29ycmVsYXRpb24gYmV0d2VlbiBDVG1heCBhbmQgdGVtcGVyYXR1cmUgdGhhbiBzaXplIGFuZCB0ZW1wZXJhdHVyZS4gVGhlcmUgYXJlIG15cmlhZCByZWFzb25zIHRoaXMgbWlnaHQgYmUgb2JzZXJ2ZWQsIGJ1dCBvbmUgcG90ZW50aWFsIGlzIHRoZSBwb3RlbnRpYWwgZm9yIGFjY2xpbWF0aW9uIG9mIHRoZXJtYWwgbGltaXRzLiBCb2R5IHNpemUgaXMgZml4ZWQgaW4gdGhlIGFkdWx0IHN0YWdlLCB3aGlsZSBDVG1heCBjYW4gY29udGludWUgdG8gdmFyeSBhcyB3YXRlciB0ZW1wZXJhdHVyZSBjaGFuZ2VzLiBUaGlzIGlzIGluZGlyZWN0IGV2aWRlbmNlIGZvciB0aGUgaW1wb3J0YW5jZSBvZiByYXBpZCBhY2NsaW1hdGlvbiBpbiB0aGUgb2JzZXJ2ZWQgcGF0dGVybnMuIAoKYGBge3IgdGVtcC1jb3JzLCBmaWcud2lkdGg9MTUsIGZpZy5oZWlnaHQ9Nn0KY3RtYXhfdGVtcF9wbG90ID0gZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBjdG1heCkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBULAogICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIsIAogICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5IikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwgCiAgICAgICAgICAgICBzaXplID0gMiwgYWxwaGEgPSAwLjcpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIkNUbWF4ICjCsEMpIiwKICAgICAgIHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpzaXplX3RlbXBfcGxvdCA9IGdncGxvdChmdWxsX2RhdGEsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gc2l6ZSkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBULAogICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIsIAogICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5IikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwgCiAgICAgICAgICAgICBzaXplID0gMiwgYWxwaGEgPSAwLjcpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIlByb3NvbWUgTGVuZ3RoIChtbSkiLAogICAgICAgeCA9ICJDb2xsZWN0aW9uIFRlbXAuICjCsEMpIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgp3dF90ZW1wX3Bsb3QgPSBnZ3Bsb3QoZnVsbF9kYXRhLCBhZXMoeCA9IGNvbGxlY3Rpb25fdGVtcCwgeSA9IHdhcm1pbmdfdG9sKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IFQsCiAgICAgICAgICAgICAgbGluZXdpZHRoID0gMiwgCiAgICAgICAgICAgICAgY29sb3VyID0gImdyZXkiKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IHNpdGUpLCAKICAgICAgICAgICAgIHNpemUgPSAyLCBhbHBoYSA9IDAuNykgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHkgPSAiV2FybWluZyBUb2xlcmFuY2UgKMKwQykiLAogICAgICAgeCA9ICJDb2xsZWN0aW9uIFRlbXAuICjCsEMpIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2UoY3RtYXhfdGVtcF9wbG90LCB3dF90ZW1wX3Bsb3QsIHNpemVfdGVtcF9wbG90LCBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gImJvdHRvbSIsIG5yb3cgPSAxKQpgYGAKCmBgYHtyIHBvcC10ZW1wLWNvcnMsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTYsIGluY2x1ZGUgPSBGfQojIFNob3duIGJlbG93IGFyZSB0aGVzZSB0ZW1wZXJhdHVyZSBjb3JyZWxhdGlvbnMgZm9yIGVhY2ggaW5kaXZpZHVhbCBwb3B1bGF0aW9uLiBWYXJpYXRpb24gaW4gdGhlIHRlbXBlcmF0dXJlIHNlbnNpdGl2aXR5IG9mIHRoZXNlIHRyYWl0cyBhcHBlYXJzIHRvIHZhcnkgYWNyb3NzIHBvcHVsYXRpb25zLCB3aXRoIHJlZHVjZWQgc2xvcGVzIGluIGJvdGggdGhlIGxvd2VzdCBhbmQgdGhlIGhpZ2hlc3QgbGF0aXR1ZGUgcG9wdWxhdGlvbnMuIEFnYWluLCB3ZSBlbXBoYXNpemUgdGhhdCB0aGlzIG9ic2VydmVkIHRyYWl0IHZhcmlhdGlvbiBtYXkgc3RlbSBmcm9tIGVpdGhlciAob3IgYm90aCkgcGxhc3RpYyBhbmQgZ2VuZXRpYyBlZmZlY3RzLiBIb3dldmVyLCB0aGVzZSBvYnNlcnZhdGlvbnMgcHJvdmlkZSBlc3RpbWF0ZXMgZm9yIHJlYWxpc3RpYyBwYXR0ZXJucyBpbiB0ZW1wZXJhdHVyZSBzZW5zaXRpdml0eSBmb3IgdGhlc2UgcG9wdWxhdGlvbnMuIAoKZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBjdG1heCkpICsgCiAgZmFjZXRfd3JhcCgufnNpdGUpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBULAogICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIsIAogICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5IikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwgCiAgICAgICAgICAgICBzaXplID0gMiwgYWxwaGEgPSAwLjcpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIkNUbWF4ICjCsEMpIiwKICAgICAgIHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpnZ3Bsb3QoZnVsbF9kYXRhLCBhZXMoeCA9IGNvbGxlY3Rpb25fdGVtcCwgeSA9IHNpemUpKSArIAogIGZhY2V0X3dyYXAoLn5zaXRlKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gVCwKICAgICAgICAgICAgICBsaW5ld2lkdGggPSAyLCAKICAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleSIpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gc2l0ZSksIAogICAgICAgICAgICAgc2l6ZSA9IDIsIGFscGhhID0gMC43KSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJQcm9zb21lIExlbmd0aCAobW0pIiwKICAgICAgIHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpgYGAKCk9uZSBhZGRpdGlvbmFsIGNvcnJlbGF0aW9uIG9mIGludGVyZXN0IGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBwcm9zb21lIGxlbmd0aCBhbmQgQ1RtYXguIEluIG1hbnkgY2FzZXMsIGxhcmdlciBib2R5IHNpemVzIGFyZSBhc3NvY2lhdGVkIHdpdGggY29sZCBhZGFwdGF0aW9uL2FjY2xpbWF0aW9uLCBhbmQgdGhlcmUgaXMgYSBnZW5lcmFsIHRyZW5kIG9mIGRlY3JlYXNpbmcgdGhlcm1hbCBsaW1pdHMgd2l0aCBpbmNyZWFzaW5nIHNpemUuIFNob3duIGJlbG93IGlzIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBwcm9zb21lIGxlbmd0aCBhbmQgQ1RtYXggaW4gb3VyIGRhdGEgc2V0LiBJbmRpdmlkdWFsIHJlZ3Jlc3Npb24gbGluZXMgZm9yIGVhY2ggc2l0ZSBhcmUgYWxzbyBpbmNsdWRlZCAtIHRoZSBkYXJrIGdyZXkgbGluZXMgaW4gdGhlIGJhY2tncm91bmQgcmVwcmVzZW50IHRoZSAndW5pdmVyc2FsJyByZWdyZXNzaW9uIGZvciB0aGF0IHNpdGUsIHdpdGggaW5kaXZpZHVhbCBjb2xvcmVkIHJlZ3Jlc3Npb24gbGluZXMgZm9yIGVhY2ggY29sbGVjdGlvbi4gQWNyb3NzIG91ciBjb2xsZWN0aW9ucywgd2Ugc2VlIGV2aWRlbmNlIGZvciB0aGlzIHJlbGF0aW9uc2hpcCwgd2l0aCBsYXJnZXIgaW5kaXZpZHVhbHMgaGF2aW5nIGxvd2VyIHRoZXJtYWwgbGltaXRzLiAgICAgIAoKYGBge3IgY3RtYXgtdnMtc2l6ZSwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9MTB9CnVuaXZlcnNhbF9zaXplID0gZnVsbF9kYXRhICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzaXplLCB5ID0gY3RtYXgpKSArIAogICMgZ2VvbV9zbW9vdGgoZGF0YSA9IGZpbHRlcihmdWxsX2RhdGEsIGN0bWF4ID4gMzEpLCAKICAjICAgICAgICAgICAgIGFlcyh4ID0gc2l6ZSwgeSA9IGN0bWF4KSwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIAogICMgICAgICAgICAgICAgY29sb3VyID0gImdyZXk2MCIsIAogICMgICAgICAgICAgICAgc2UgPSBGLAogICMgICAgICAgICAgICAgbGluZXdpZHRoID0gMikgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IFQsCiAgICAgICAgICAgICAgbGluZXdpZHRoID0gMiwKICAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTcwIikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwKICAgICAgICAgICAgIHNpemUgPSAyLCBhbHBoYSA9IDAuNykgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHkgPSAiQ1RtYXggKMKwQykiLAogICAgICAgeCA9ICIiKSArCiAgdGhlbWVfbWF0dChiYXNlX3NpemUgPSAxNCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSkKCnBvcF9zaXplID0gZnVsbF9kYXRhICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBzaXplLCB5ID0gY3RtYXgsIGNvbG91ciA9IHNpdGUsIGdyb3VwID0gc2Vhc29uKSkgKyAKICBmYWNldF93cmFwKHNpdGV+LikgKyAKICAjIGdlb21fc21vb3RoKGRhdGEgPSBmaWx0ZXIoZnVsbF9kYXRhLCBjdG1heCA+IDMxKSwgCiAgIyAgICAgICAgICAgICBhZXMoeCA9IHNpemUsIHkgPSBjdG1heCksCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCAKICAjICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5NjAiLCAKICAjICAgICAgICAgICAgIHNlID0gRiwKICAjICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIpICsgCiAgZ2VvbV9zbW9vdGgoZGF0YSA9IGZ1bGxfZGF0YSwgCiAgICAgICAgICAgICAgYWVzKHggPSBzaXplLCB5ID0gY3RtYXgsIGdyb3VwID0gc2l0ZSksIAogICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5MjAiLCBtZXRob2QgPSAibG0iLCBzZSA9IEYpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMS4zLCBhbHBoYSA9IDAuMykgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEYsCiAgICAgICAgICAgICAgbGluZXdpZHRoID0gMSkgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYygwLjYsIDAuOCwgMSkpICsgCiAgbGFicyh5ID0gIkNUbWF4ICjCsEMpIiwKICAgICAgIHggPSAiUHJvc29tZSBMZW5ndGggKG1tKSIpICsKICB0aGVtZV9tYXR0KGJhc2Vfc2l6ZSA9IDE0KSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2UodW5pdmVyc2FsX3NpemUsIHBvcF9zaXplLCBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gIm5vbmUiLCBucm93ID0gMikKYGBgCgpUaGlzIHJlbGF0aW9uc2hpcCBtYXkgYmUgYWZmZWN0ZWQgYnkgY2hhbmdlcyBpbiB0ZW1wZXJhdHVyZSBhdCBlYWNoIHNpdGUsIGhvd2V2ZXIsIHdoaWNoIGNhbiBhZmZlY3QgYm90aCBib2R5IHNpemUgYW5kIHRoZXJtYWwgbGltaXRzLiBJZiB0aGVyZSBpcyBhIHRydWUgbWVjaGFuaXN0aWMgcmVsYXRpb25zaGlwIGJldHdlZW4gYm9keSBzaXplIGFuZCB0aGVybWFsIGxpbWl0cywgd2Ugd291bGQgZXhwZWN0IHRvIHNlZSB0aGlzIHJlbGF0aW9uc2hpcCBlbWVyZ2UgKip3aXRoaW4qKiBwb3B1bGF0aW9ucywgb3IgZXZlbiBpbmRpdmlkdWFsIGNvbGxlY3Rpb25zLiBTaG93biBiZWxvdyBpcyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gQ1RtYXggYW5kIHNpemUgcmVzaWR1YWxzLCBhY3F1aXJlZCBmcm9tIHJlZ3Jlc3Npb25zIG9mIHRoZXNlIHRyYWl0cyBhZ2FpbnN0IGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUuIFRoaXMgc3Vic3RhbnRpYWxseSByZWR1Y2VzIHRoZSBzdHJlbmd0aCBvZiB0aGUgYXBwYXJlbnQgcmVsYXRpb25zaGlwLCBidXQgdGhlcmUgaXMgc3RpbGwgYSBzbGlnaHRseSBuZWdhdGl2ZSBvdmVyYWxsIHJlbGF0aW9uc2hpcCwgc3Bhbm5pbmcgYm90aCBhY3Jvc3MtcG9wdWxhdGlvbiwgd2l0aGluLXBvcHVsYXRpb24sIGFuZCBldmVuIHdpdGhpbi1jb2xsZWN0aW9uIHNjYWxlcyAoc2VlIHRoZSBTYXd5ZXIgUGFyayBjb2xsZWN0aW9ucywgZm9yIGV4YW1wbGUpLiAgICAgCgpgYGB7ciBjdG1heC12cy1zaXplLXJlc2lkcywgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9MTB9CmZpbHRlcmVkX2RhdGEgPSBmdWxsX2RhdGEgJT4lIAogIGRyb3BfbmEoc2l6ZSwgY3RtYXgpICU+JSAKICBtdXRhdGUodGVtcF9jZW50ID0gc2NhbGUoY29sbGVjdGlvbl90ZW1wLCBzY2FsZSA9IEYpLAogICAgICAgICBzaXplX2NlbnQgPSBzY2FsZShzaXplLCBzY2FsZSA9IEYpLAogICAgICAgICBzYWxfY2VudCA9IHNjYWxlKGNvbGxlY3Rpb25fc2FsaW5pdHksIHNjYWxlID0gRiksCiAgICAgICAgIHNhbF90eXBlID0gaWZfZWxzZShjb2xsZWN0aW9uX3NhbGluaXR5ID4gMjAsICJIaWdoIiwgIkxvdyIpKQoKY3RtYXhfdGVtcC5tb2RlbCA9IGxtKGN0bWF4IH4gY29sbGVjdGlvbl90ZW1wICsgc2l0ZSwgZGF0YSA9IGZpbHRlcmVkX2RhdGEpCmN0bWF4X3Jlc2lkcyA9IHJlc2lkdWFscyhjdG1heF90ZW1wLm1vZGVsKQoKc2l6ZV90ZW1wLm1vZGVsID0gbG0oc2l6ZSB+IGNvbGxlY3Rpb25fdGVtcCArIHNpdGUsIGRhdGEgPSBmaWx0ZXJlZF9kYXRhKQpzaXplX3Jlc2lkcyA9IHJlc2lkdWFscyhzaXplX3RlbXAubW9kZWwpCgp1bml2ZXJzYWxfcmVzaWRzID0gZmlsdGVyZWRfZGF0YSAlPiUgCiAgbXV0YXRlKGN0bWF4X3Jlc2lkcyA9IGN0bWF4X3Jlc2lkcywKICAgICAgICAgc2l6ZV9yZXNpZHMgPSBzaXplX3Jlc2lkcykgCgphbGxfcmVzaWRzID0gZ2dwbG90KHVuaXZlcnNhbF9yZXNpZHMsIGFlcyh4ID0gc2l6ZV9yZXNpZHMsIHkgPSBjdG1heF9yZXNpZHMpKSArIAogICMgZ2VvbV9zbW9vdGgoZGF0YSA9IGZpbHRlcihmdWxsX2RhdGEsIGN0bWF4ID4gMzEpLCAKICAjICAgICAgICAgICAgIGFlcyh4ID0gc2l6ZSwgeSA9IGN0bWF4KSwKICAjICAgICAgICAgICAgIG1ldGhvZCA9ICJsbSIsIAogICMgICAgICAgICAgICAgY29sb3VyID0gImdyZXk2MCIsIAogICMgICAgICAgICAgICAgc2UgPSBGLAogICMgICAgICAgICAgICAgbGluZXdpZHRoID0gMikgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IFQsCiAgICAgICAgICAgICAgbGluZXdpZHRoID0gMiwKICAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTcwIikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwKICAgICAgICAgICAgIHNpemUgPSAyLCBhbHBoYSA9IDAuNykgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHkgPSAiQ1RtYXggUmVzaWR1YWxzIiwKICAgICAgIHggPSAiIikgKwogIHRoZW1lX21hdHQoYmFzZV9zaXplID0gMTQpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCkpCgpwb3BfcmVzaWRzID0gZ2dwbG90KHVuaXZlcnNhbF9yZXNpZHMsIGFlcyh4ID0gc2l6ZV9yZXNpZHMsIHkgPSBjdG1heF9yZXNpZHMsIGNvbG91ciA9IHNpdGUsIGdyb3VwID0gc2Vhc29uKSkgKyAKICBmYWNldF93cmFwKHNpdGV+LikgKyAKICAjIGdlb21fc21vb3RoKGRhdGEgPSBmaWx0ZXIoZnVsbF9kYXRhLCBjdG1heCA+IDMxKSwgCiAgIyAgICAgICAgICAgICBhZXMoeCA9IHNpemUsIHkgPSBjdG1heCksCiAgIyAgICAgICAgICAgICBtZXRob2QgPSAibG0iLCAKICAjICAgICAgICAgICAgIGNvbG91ciA9ICJncmV5NjAiLCAKICAjICAgICAgICAgICAgIHNlID0gRiwKICAjICAgICAgICAgICAgIGxpbmV3aWR0aCA9IDIpICsgCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSBzaXplX3Jlc2lkcywgeSA9IGN0bWF4X3Jlc2lkcywgZ3JvdXAgPSBzaXRlKSwgCiAgICAgICAgICAgICAgY29sb3VyID0gImdyZXkyMCIsIG1ldGhvZCA9ICJsbSIsIHNlID0gRikgKyAKICBnZW9tX3BvaW50KHNpemUgPSAxLjMsIGFscGhhID0gMC4zKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRiwKICAgICAgICAgICAgICBsaW5ld2lkdGggPSAxKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCBSZXNpZHVhbHMiLAogICAgICAgeCA9ICJQcm9zb21lIExlbmd0aCBSZXNpZHVhbHMiKSArCiAgdGhlbWVfbWF0dChiYXNlX3NpemUgPSAxNCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKZ2dhcnJhbmdlKGFsbF9yZXNpZHMsIHBvcF9yZXNpZHMsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAibm9uZSIsIG5yb3cgPSAyKQpgYGAKCmBgYHtyIGN0bWF4LW1vZGVsLCBpbmNsdWRlID0gRn0KY3RtYXgubW9kZWwgPSBsbWU0OjpsbWVyKAogIGRhdGEgPSBmaWx0ZXJlZF9kYXRhLCAKICBjdG1heCB+IHRlbXBfY2VudCArIHNpemUgKyBzYWxfdHlwZSArICgxICsgdGVtcF9jZW50fHNpdGUpICsgKDF8c2Vhc29uKSkKYGBgCgpUbyBtb3JlIGZvcm1hbGx5IHRlc3QgdGhlIHJlbGF0aW9uc2hpcHMgYmV0d2VlbiBDVG1heCwgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSwgYW5kIHNpemUsIHdlIHVzZWQgYSBsaW5lYXIgbWl4ZWQgZWZmZWN0cyBtb2RlbCwgc3RydWN0dXJlZCBhcyBgY3RtYXggfiBjb2xsZWN0aW9uIHRlbXAuICsgc2l6ZSArIHNhbGluaXR5ICsgKDEgKyBjb2xsZWN0aW9uIHRlbXAufHNpdGUpYC4gVGhpcyBleGFtaW5lcyB0aGUgZWZmZWN0cyBvZiB0ZW1wZXJhdHVyZSBhbmQgc2l6ZSBvbiBDVG1heCwgYWxvbmcgd2l0aCBkaWZmZXJlbmNlcyBiZXR3ZWVuIHRoZSBzYWxpbml0eSBncm91cGluZ3MuIENvbGxlY3Rpb24gdGVtcGVyYXR1cmUgYW5kIHNpemUgd2VyZSBib3RoIGNlbnRlcmVkIGFuZCBzYWxpbml0eSB0cmFuc2Zvcm1lZCBpbnRvIGEgY2F0ZWdvcmljYWwgdmFyaWFibGUgKCJsb3ciIHNhbGluaXR5IGFzIGFueXRoaW5nIGJlbG93IDIwIHBzdSwgImhpZ2giIHNhbGluaXR5IGFzIGFueXRoaW5nIGFib3ZlIDIwIHBzdSkgYmVmb3JlIG1vZGVsIGZpdHRpbmcuIFRoZSBtb2RlbCBhbHNvIGluY2x1ZGVzIHJhbmRvbSBpbnRlcmNlcHRzIGZvciBlYWNoIHNpdGUgYW5kIHJhbmRvbSBzbG9wZXMgZm9yIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUgKGkuZS4gLSB2YXJpYXRpb24gaW4gdGhlIGFjY2xpbWF0aW9uIGNhcGFjaXR5IG9mIENUbWF4KS4gQSByYW5kb20gaW50ZXJjZXB0IGZvciBzZWFzb24gaXMgYWxzbyBpbmNsdWRlZC4gCgpDb2xsZWN0aW9uIHRlbXBlcmF0dXJlIGFuZCBib2R5IHNpemUgYm90aCBoYWQgYSBzaWduaWZpY2FudCBlZmZlY3Qgb24gQ1RtYXgsIGJ1dCBzYWxpbml0eSB0eXBlIGRpZCBub3QuIFRoZSBvdmVyYWxsIGVmZmVjdCBvZiB0ZW1wZXJhdHVyZSBzdWdnZXN0cyBhbiBpbmNyZWFzZSBpbiBDVG1heCBvZiBgciByb3VuZCh1bm5hbWUoZml4ZWYoY3RtYXgubW9kZWwpWyJ0ZW1wX2NlbnQiXSksIGRpZ2l0cyA9IDIpYMKwQyBwZXIgwrBDIGluY3JlYXNlIGluIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUgKGkuZS4gLSBhbiBBUlIgdmFsdWUgb2YgYHIgcm91bmQodW5uYW1lKGZpeGVmKGN0bWF4Lm1vZGVsKVsidGVtcF9jZW50Il0pLCBkaWdpdHMgPSAyKWApLCB3aGlsZSBpbmNyZWFzaW5nIGJvZHkgc2l6ZXMgZGVjcmVhc2UgQ1RtYXggYnkgYHIgcm91bmQodW5uYW1lKGZpeGVmKGN0bWF4Lm1vZGVsKVsic2l6ZSJdKSwgZGlnaXRzID0gMilgwrBDIHBlciBtbSAob3IgYSBkZWNyZWFzZSBvZiB+YHIgcm91bmQodW5uYW1lKGZpeGVmKGN0bWF4Lm1vZGVsKVsic2l6ZSJdKSwgZGlnaXRzID0gMikvMTBgwrBDIHBlciB0ZW50aCBvZiBhIG1tLCB3aGljaCBpcyBtb3JlIGJpb2xvZ2ljYWxseSByZWFsaXN0aWMgZm9yICpBLiB0b25zYSopLiBXaGlsZSBub3Qgc2lnbmlmaWNhbnQsIHRoZSBtb2RlbCBzdWdnZXN0cyBsb3cgc2FsaW5pdHkgc2l0ZXMgaGFkIGxvd2VyIHRoZXJtYWwgbGltaXRzIGJ5IH5gciBhYnMocm91bmQodW5uYW1lKGZpeGVmKGN0bWF4Lm1vZGVsKVsic2FsX3R5cGVMb3ciXSksIGRpZ2l0cyA9IDEpKWDCsEMuCgpgYGB7cn0KCmVmZmVjdHNfc3VtbWFyeSA9IGRhdGEuZnJhbWUoCiAgIlRlbXBlcmF0dXJlIiA9IHVubmFtZShmaXhlZihjdG1heC5tb2RlbClbInRlbXBfY2VudCJdKSwKICAiU2l6ZSIgPSB1bm5hbWUoZml4ZWYoY3RtYXgubW9kZWwpWyJzaXplIl0pLAogICJTYWxpbml0eSIgPSB1bm5hbWUoZml4ZWYoY3RtYXgubW9kZWwpWyJzYWxfdHlwZUxvdyJdKSkgJT4lICAKICBzZWxlY3QoIlRlbXBlcmF0dXJlIChwZXIgZGVncmVlKSIgPSBUZW1wZXJhdHVyZSwgCiAgICAgICAgICJTaXplIChwZXIgbW0pIiA9IFNpemUsIAogICAgICAgICAiU2FsaW5pdHkgKExvdyB2cy4gSGlnaCkiID0gU2FsaW5pdHkpCgprbml0cjo6a2FibGUoZWZmZWN0c19zdW1tYXJ5KQpgYGAKCkJ5IGV4dHJhY3RpbmcgdGhlIGNvbmRpdGlvbmFsIG1vZGUgZm9yIHRoZSByYW5kb20gZWZmZWN0cywgd2UgY2FuIGFsc28gZXhhbWluZSBob3cgdGhlcm1hbCBsaW1pdHMgdmFyeSBhY3Jvc3Mgc2l0ZXMgYmV5b25kIHRoZSBpbmZsdWVuY2Ugb2YgY29sbGVjdGlvbiB0ZW1wZXJhdHVyZXMgYW5kIGJvZHkgc2l6ZXMuIFNob3duIGJlbG93IGFyZSB0aGVzZSAicG9wdWxhdGlvbiIgdmFsdWVzIChlc3NlbnRpYWxseSwgYWxsIGVsc2UgYmVpbmcgZXF1YWwsIGhvdyB3b3VsZCB0aGVybWFsIGxpbWl0IHZhcnkgYWNyb3NzIHBvcHVsYXRpb25zKS4gV2UgY2FuIHNlZSB0aGF0LCBzaW1pbGFyIHRvIHdoYXQncyBiZWVuIG9ic2VydmVkIGluIGNvbW1vbiBnYXJkZW4gZXhwZXJpbWVudHMgd2l0aCAqQS4gdG9uc2EqIHByZXZpb3VzbHksIHNpZ25pZmljYW50IGRpdmVyZ2VuY2VzIGFyZSBwcmVzZW50IGF0IG9ubHkgYSBmZXcgc2l0ZXMgbmVhciB0aGUgbGF0aXR1ZGluYWwgZXh0cmVtZXMsIHdpdGggRm9ydCBIYW1lciBhbmQgUml0Y2hpZSBXaGFyZiBoYXZpbmcgaW5jcmVhc2VkIGFuZCBkZWNyZWFzZWQgdGhlcm1hbCBsaW1pdHMgcmVzcGVjdGl2ZWx5LiBJbnRlcmVzdGluZ2x5LCBib3RoIG9mIHRoZXNlIHNpdGVzIHdlcmUgbG93IHNhbGluaXR5IHNpdGVzLCBhbHNvIGluIGxpbmUgd2l0aCBwcmV2aW91cyByZXN1bHRzIHN1Z2dlc3RpbmcgZ2VuZSBmbG93IGJldHdlZW4gaGlnaCBzYWxpbml0eSBzaXRlcyBtYXkgY29uc3RyYWluIGRpZmZlcmVudGlhdGlvbi4gCgpgYGB7ciBwb3AtZWZmcy1wbG90LCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD02fQpwb3BfZWZmcyA9IFJFc2ltKGN0bWF4Lm1vZGVsKSAlPiUgCiAgZHBseXI6OnNlbGVjdCgic2l0ZSIgPSBncm91cElELCB0ZXJtLCBtZWFuLCBzZCkgJT4lIAogIGZpbHRlcih0ZXJtID09ICIoSW50ZXJjZXB0KSIpICU+JSAKICBpbm5lcl9qb2luKHNpdGVfZGF0YSwgYnkgPSBjKCJzaXRlIikpICU+JSAKICBtdXRhdGUoc2l0ZSA9IGZjdF9yZW9yZGVyKHNpdGUsIGxhdCkpCgpzZWFzb25fZWZmcyA9IFJFc2ltKGN0bWF4Lm1vZGVsKSAlPiUgCiAgZHBseXI6OnNlbGVjdCgic2l0ZSIgPSBncm91cElELCB0ZXJtLCBtZWFuLCBzZCkgJT4lIAogIGZpbHRlcihzaXRlICVpbiUgYygiZWFybHkiLCAicGVhayIsICJsYXRlIikpICU+JSAKICBzZWxlY3QoInNlYXNvbiIgPSBzaXRlLCBtZWFuLCBzZCkKCiNwbG90UkVzaW0oUkVzaW0oY3RtYXgubW9kZWwpKSAgIyBwbG90IHRoZSBpbnRlcnZhbCBlc3RpbWF0ZXMKCnBvcF9lZmZzX3Bsb3QgPSBnZ3Bsb3QocG9wX2VmZnMsIGFlcyh4ID0gbGF0LCB5ID0gbWVhbiwgY29sb3VyID0gc2l0ZSkpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgY29sb3VyID0gImdyZXkiKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IG1lYW4gLSAxLjk2ICogc2QsIHltYXggPSBtZWFuICsgMS45NiAqIHNkKSwKICAgICAgICAgICAgICAgIHdpZHRoID0gMC41LCBsaW5ld2lkdGggPSAxKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh4ID0gIkxhdGl0dWRlIiwgCiAgICAgICB5ID0gIlBvcHVsYXRpb24gRWZmZWN0IikgKyAKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKcG9wX2VmZnNfcGxvdApgYGAKCkZpbmFsbHksIHNob3duIGJlbG93IGFyZSB0aGUgZXN0aW1hdGVkIHJhbmRvbSBzbG9wZXMgZm9yIGVhY2ggc2l0ZS4gVGhlc2UgcmVwcmVzZW50IHRoZSBlZmZlY3RzIG9mIGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUgb24gQ1RtYXggZm9yIGVhY2ggc2l0ZS4gSW50ZXJlc3RpbmdseSwgdGhlc2UgZXN0aW1hdGVzIGRpdmVyZ2UgZnJvbSB0aGUgcmVzdWx0cyBvZiBwcmV2aW91cyBjb21tb24gZ2FyZGVuIGV4cGVyaW1lbnRzLCB3aGljaCBzaG93ZWQgdGhlIHN0cm9uZ2VzdCBwbGFzdGljaXR5IGluIGhpZ2ggbGF0aXR1ZGUgc2l0ZXMuIEhlcmUsIGFjY2xpbWF0aW9uIGFwcGVhcnMgdG8gcGVhayBpbiBtaWQtbGF0aXR1ZGVzLCBhbmQgZGVjcmVhc2UgYXQgYm90aCBoaWdoIGFuZCBsb3cgbGF0aXR1ZGUgc2l0ZXMuIFRoaXMgc3VnZ2VzdHMgZmFjdG9ycyBtYXkgY29uc3RyYWluIGFjY2xpbWF0aW9uIGNhcGFjaXR5IGluIG5hdHVyYWwgcG9wdWxhdGlvbnMgKGUuZy4gZm9vZCBhdmFpbGFiaWxpdHksIGVudmlyb25tZW50YWwgdmFyaWF0aW9uLCBwYXRob2dlbnMsIGV0Yy4pLiAKCmBgYHtyIHNpdGUtYXJyLXBsb3QsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9CmNvZWZmaWNpZW50cyhjdG1heC5tb2RlbCkkc2l0ZSAlPiUKICBqYW5pdG9yOjpjbGVhbl9uYW1lcygpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbih2YXIgPSAic2l0ZSIpICU+JQogIGlubmVyX2pvaW4oc2l0ZV9kYXRhKSAlPiUgCiAgbXV0YXRlKHNpdGUgPSBmY3RfcmVvcmRlcihzaXRlLCBsYXQpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gdGVtcF9jZW50LCB5ID0gc2l0ZSkpICsKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwKICAgICAgICAgICAgIHNpemUgPSA1KSArCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsKICBsYWJzKHggPSAiQVJSIikgKyAKICB0aGVtZV9tYXR0KCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwKICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCkpCmBgYAoKIyMgVHJhaXQgVmFyaWFiaWxpdHkKClNob3duIGJlbG93IGlzIHRoZSB0cmFpdCB2YXJpYXRpb24gKHJhbmdlcykgZm9yIGVhY2ggc2l0ZS4gUmFuZ2VzIGFyZSBjYWxjdWxhdGVkIGZvciBlYWNoIGNvbGxlY3Rpb24gc2VwYXJhdGVseS4gCgpgYGB7ciB0cmFpdC1yYW5nZS1wbG90LCBmaWcud2lkdGg9MTIsIGZpZy5oZWlnaHQ9NC41fQp0cmFpdF9yYW5nZXMgPSBmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHNpdGUsIHNlYXNvbiwgY29sbGVjdGlvbl90ZW1wLCBjb2xsZWN0aW9uX3NhbGluaXR5LCBkb3ksIGxhdCkgJT4lIAogIHN1bW1hcmlzZShtZWFuX2N0bWF4ID0gbWVhbihjdG1heCksCiAgICAgICAgICAgIGN0bWF4X3JhbmdlID0gbWF4KGN0bWF4KSAtIG1pbihjdG1heCksCiAgICAgICAgICAgIGN0bWF4X3ZhciA9IHZhcihjdG1heCksCiAgICAgICAgICAgIG1lYW5fc2l6ZSA9IG1lYW4oc2l6ZSksCiAgICAgICAgICAgIHNpemVfcmFuZ2UgPSBtYXgoc2l6ZSkgLSBtaW4oc2l6ZSksCiAgICAgICAgICAgIHNpemVfdmFyID0gdmFyKHNpemUpKSAlPiUgCiAgbXV0YXRlKHByb3BfY3RtYXhfcmFuZ2UgPSBjdG1heF9yYW5nZSAvIG1lYW5fY3RtYXgsCiAgICAgICAgIHByb3Bfc2l6ZV9yYW5nZSA9IHNpemVfcmFuZ2UgLyBtZWFuX3NpemUpCgpjdG1heF9yYW5nZV90ZW1wID0gZ2dwbG90KHRyYWl0X3JhbmdlcywgYWVzKHggPSBjb2xsZWN0aW9uX3RlbXAsIHkgPSBjdG1heF9yYW5nZSkpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgY29sb3VyID0gImJsYWNrIikgKyAKICBnZW9tX3BvaW50KGFlcyhjb2xvdXIgPSBzaXRlKSwgCiAgICAgICAgICAgICBzaXplID0gMykgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHkgPSAiQ1RtYXggUmFuZ2UgKMKwQykiLAogICAgICAgeCA9ICJDb2xsZWN0aW9uIFRlbXAuICjCsEMpIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpjdG1heF92YXJfdGVtcCA9IGdncGxvdCh0cmFpdF9yYW5nZXMsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gY3RtYXhfdmFyLCBjb2xvdXIgPSBzaXRlKSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCBSYW5nZSAowrBDKSIsCiAgICAgICB4ID0gIkNvbGxlY3Rpb24gVGVtcC4gKMKwQykiKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCnNpemVfcmFuZ2VfdGVtcCA9IGdncGxvdCh0cmFpdF9yYW5nZXMsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gc2l6ZV9yYW5nZSwgY29sb3VyID0gc2l0ZSkpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMykgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHkgPSAiU2l6ZSBSYW5nZSAobW0pIiwKICAgICAgIHggPSAiQ29sbGVjdGlvbiBUZW1wLiAowrBDKSIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiKQoKc2l6ZV92YXJfdGVtcCA9IGdncGxvdCh0cmFpdF9yYW5nZXMsIGFlcyh4ID0gY29sbGVjdGlvbl90ZW1wLCB5ID0gc2l6ZV92YXIsIGNvbG91ciA9IHNpdGUpKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIlNpemUgUmFuZ2UgKG1tKSIsCiAgICAgICB4ID0gIkNvbGxlY3Rpb24gVGVtcC4gKMKwQykiKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCmdnYXJyYW5nZShjdG1heF9yYW5nZV90ZW1wLCBzaXplX3JhbmdlX3RlbXAsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAicmlnaHQiKQpgYGAKCkNoYW5nZXMgaW4gdHJhaXQgdmFyaWFuY2UgbWF5IGJlIGluZGljYXRpdmUgb2YgcGhlbm90eXBpYyBzZWxlY3Rpb24uIElmIHNlbGVjdGlvbiAoYXMgb3Bwb3NlZCB0byBhY2NsaW1hdGlvbikgYXJlIGRyaXZpbmcgc2Vhc29uYWwgY2hhbmdlcywgd2UgbWF5IGV4cGVjdCB0byBzZWUgYSByZWR1Y3Rpb24gaW4gdmFyaWFuY2UgaW4gdGhlIHBlYWsgc2FtcGxlcyByZWxhdGl2ZSB0byB0aGUgZWFybHkgc2Vhc29uIHNhbXBsZXMuIE5vdGUgdGhhdCBlYXJseSBzZWFzb24gY29sbGVjdGlvbiB0ZW1wZXJhdHVyZXMgdGhpcyB5ZWFyIHdlcmUgaGlnaGVyIHRoYW4gZXhwZWN0ZWQsIGRyaXZlbiBieSBmYWlybHkgc3Ryb25nIGhlYXR3YXZlcyBhY3Jvc3MgdGhlIE5vcnRoIEF0bGFudGljLiBBcyBzaG93biBpbiB0aGUgdGVtcGVyYXR1cmUgcHJvZmlsZXMgZm9yIGVhY2ggc2l0ZSwgdGhlICdlYXJseScgc2FtcGxlcyB3ZXJlIGNvbGxlY3RlZCBqdXN0IGFmdGVyIGhpZ2ggdGVtcGVyYXR1cmVzIHdlcmUgcmVhY2hlZCwgd2hpbGUgJ3BlYWsnIHNhbXBsZXMgd2VyZSBjb2xsZWN0ZWQgYWZ0ZXIgc2l0ZXMgaGFkIGV4cGVyaWVuY2VkIGhpZ2ggdGVtcGVyYXR1cmVzIGZvciBzZXZlcmFsIHdlZWtzIChnZW5lcmF0aW9ucykuIEFzIHdhcm1pbmcgdG9sZXJhbmNlcyB3ZXJlIGZhaXJseSBoaWdoIHRocm91Z2hvdXQgdGhpcyBwZXJpb2QsIHdlIHdpbGwgYXNzdW1lIHRoYXQgc2VsZWN0aW9uIHdhcyB3ZWFrIGJlZm9yZSB0aGUgZWFybHkgc2FtcGxlcy4gSWYgdGhlIGVhcmx5IG9uc2V0IG9mIGhpZ2ggdGVtcGVyYXR1cmVzIGZpbHRlcmVkIG91dCB2dWxuZXJhYmxlIGdlbm90eXBlcyBwcmlvciB0byBvdXIgc2FtcGxpbmcsIHRoZSByZXN1bHRzIHdpbGwgYmUgYSBjb25zZXJ2YXRpdmUgZXN0aW1hdGUgb2YgdGhlIGVmZmVjdHMgb2Ygc2VsZWN0aW9uIG9uIHRyYWl0IHZhcmlhbmNlLiAgICAgCgpTaG93biBiZWxvdyBpcyB0aGUgc2Vhc29uYWwgcHJvZ3Jlc3Npb24gb2YgdmFyaWFuY2UgaW4gQ1RtYXggZm9yIGVhY2ggc2l0ZS4gRm9yIG1hbnkgc2l0ZXMsIHZhcmlhbmNlIGRlY3JlYXNlZCBiZXR3ZWVuIHRoZSBlYXJseSBhbmQgcGVhayBzYW1wbGVzLCBhbmQgdGhlbiBpbmNyZWFzZWQgYWdhaW4gaW4gdGhlIGxhdGUgc2FtcGxlLiBGb3Igc29tZSBzaXRlcyAoZS5nLiBFc2tlciBQb2ludCksIHRoaXMgaW5jcmVhc2UgaW4gdGhlIGxhdGUgc2FtcGxlIHdhcyBzdWJzdGFudGlhbC4gCgpgYGB7ciBzZWFzb24tdmFyfQpnZ3Bsb3QodHJhaXRfcmFuZ2VzLCBhZXMoeCA9IHNlYXNvbiwgeSA9IGN0bWF4X3ZhciwgY29sb3VyID0gc2l0ZSkpICsgCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHNpdGUpLCAKICAgICAgICAgICAgbGluZXdpZHRoID0gMS41KSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIkNUbWF4IFZhcmlhbmNlIiwKICAgICAgIHggPSAiU2Vhc29uIikgKwogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIAogICAgICAgIGxlZ2VuZC50aXRsZS5hbGlnbiA9IDAuMTI1KQpgYGAKClNob3duIGJlbG93IGlzIHRoZSBzZWFzb25hbCBwcm9ncmVzc2lvbiBvZiB2YXJpYW5jZSBpbiBib2R5IHNpemUuIEEgc2ltaWxhciBwYXR0ZXJuIG9mIGRlY3JlYXNpbmcgdmFyaWFuY2UgaW4gcGVhayBzYW1wbGVzIHJlbGF0aXZlIHRvIGVhcmx5IGFuZCBsYXRlIHNhbXBsZXMgaXMgYWdhaW4gc2VlbiBmb3IgbWFueSBzaXRlcy4gVGhlIG9idmlvdXMgZXhjZXB0aW9uIGlzIHRoZSBFc2tlciBQb2ludCBzYW1wbGUsIHdoaWNoIHNhdyB0aGUgb3Bwb3NpdGUgdHJlbmQuIAoKYGBge3J9CmdncGxvdCh0cmFpdF9yYW5nZXMsIGFlcyh4ID0gc2Vhc29uLCB5ID0gc2l6ZV92YXIsIGNvbG91ciA9IHNpdGUpKSArIAogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzaXRlKSwgCiAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEuNSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCBWYXJpYW5jZSIsCiAgICAgICB4ID0gIlNlYXNvbiIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgpTaG93biBiZWxvdyBhcmUgdGhlIHNlYXNvbmFsIGNoYW5nZXMgaW4gdHJhaXQgdmFyaWFuY2UgZm9yIGVhY2ggc2l0ZSBpbmRpdmlkdWFsbHkuIAoKYGBge3IgdmFyLWluZC1wb3BzLXNlYXNvbiwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Nn0KZ2dwbG90KHRyYWl0X3JhbmdlcywgYWVzKHggPSBzZWFzb24sIHkgPSBjdG1heF92YXIsIGNvbG91ciA9IHNpdGUpKSArIAogIGZhY2V0X3dyYXAoc2l0ZX4uKSArIAogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBzaXRlKSwgCiAgICAgICAgICAgIGxpbmV3aWR0aCA9IDEuNSkgKyAKICBnZW9tX3BvaW50KHNpemUgPSAzKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeSA9ICJDVG1heCBWYXJpYW5jZSIsCiAgICAgICB4ID0gIlNlYXNvbiIpICsKICB0aGVtZV9tYXR0KCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIAogICAgICAgIGxlZ2VuZC50aXRsZS5hbGlnbiA9IDAuMTI1KQoKZ2dwbG90KHRyYWl0X3JhbmdlcywgYWVzKHggPSBzZWFzb24sIHkgPSBzaXplX3ZhciwgY29sb3VyID0gc2l0ZSkpICsgCiAgZmFjZXRfd3JhcChzaXRlfi4pICsgCiAgZ2VvbV9saW5lKGFlcyhncm91cCA9IHNpdGUpLCAKICAgICAgICAgICAgbGluZXdpZHRoID0gMS41KSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh5ID0gIlNpemUgVmFyaWFuY2UiLAogICAgICAgeCA9ICJTZWFzb24iKSArCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiLCAKICAgICAgICBsZWdlbmQudGl0bGUuYWxpZ24gPSAwLjEyNSkKYGBgCgpgYGB7ciB2YXItY2hhbmdlLXRlbXAtY2hhbmdlLCBpbmNsdWRlID0gRn0KdmFyX2NoYW5nZV9kYXRhID0gdHJhaXRfcmFuZ2VzICU+JSAgCiAgdW5ncm91cCgpICU+JSAKICBtdXRhdGUobWVhbl93dCA9IG1lYW5fY3RtYXggLSBjb2xsZWN0aW9uX3RlbXApICU+JSAKICBncm91cF9ieShzaXRlKSAlPiUgCiAgYXJyYW5nZShzaXRlLCBkb3kpICU+JSAgCiAgbXV0YXRlKHRlbXBfY2hhbmdlID0gY29sbGVjdGlvbl90ZW1wIC0gbGFnKGNvbGxlY3Rpb25fdGVtcCksCiAgICAgICAgIGN0bWF4X2NoYW5nZSA9IG1lYW5fY3RtYXggLSBsYWcobWVhbl9jdG1heCksCiAgICAgICAgIHd0X2NoYW5nZSA9IG1lYW5fd3QgLSBsYWcobWVhbl93dCksCiAgICAgICAgIHZhcl9jaGFuZ2UgPSBjdG1heF92YXIgLSBsYWcoY3RtYXhfdmFyKSkgJT4lICAKICBzZWxlY3Qoc2l0ZSwgc2Vhc29uLCBkb3ksIGxhdCwgdGVtcF9jaGFuZ2UsIHZhcl9jaGFuZ2UsIGN0bWF4X2NoYW5nZSwgd3RfY2hhbmdlKQoKZ2dwbG90KHZhcl9jaGFuZ2VfZGF0YSwgYWVzKHggPSB0ZW1wX2NoYW5nZSwgeSA9IHZhcl9jaGFuZ2UpKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKyAKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAwKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIikgKwogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IHNpdGUpLAogICAgICAgICAgICAgc2l6ZSA9IDMpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh4ID0gIlRlbXBlcmF0dXJlIENoYW5nZSAowrBDKSIsCiAgICAgICB5ID0gIkNoYW5nZSBpbiBDVG1heCBWYXJpYW5jZSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgCiAgICAgICAgbGVnZW5kLnRpdGxlLmFsaWduID0gMC4xMjUpCgp2YXJfY2hhbmdlX2RhdGEgJT4lIAogIG11dGF0ZShzYW1wbGVfYXJyID0gY3RtYXhfY2hhbmdlL3RlbXBfY2hhbmdlKSAlPiUgCiAgc2VsZWN0KHNpdGUsIHNlYXNvbiwgdGVtcF9jaGFuZ2UsIHNhbXBsZV9hcnIpICU+JSAKICBkcm9wX25hKCkgJT4lIAogIGdncGxvdChhZXMoeCA9IHRlbXBfY2hhbmdlLCB5ID0gc2FtcGxlX2FyciwgY29sb3VyID0gc2l0ZSkpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgCgp2YXJfY2hhbmdlX2RhdGEgJT4lIAogIG11dGF0ZShzYW1wbGVfYXJyID0gY3RtYXhfY2hhbmdlL3RlbXBfY2hhbmdlKSAlPiUgCiAgc2VsZWN0KHNpdGUsIHNlYXNvbiwgdGVtcF9jaGFuZ2UsIHNhbXBsZV9hcnIpICU+JSAKICBkcm9wX25hKCkgJT4lIAogIGdncGxvdChhZXMoeCA9IHNhbXBsZV9hcnIpKSArIAogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC4xKQoKYGBgCgpgYGB7cn0KCmtuaXRyOjprbml0X2V4aXQoKQoKYGBgCgoKIyMgQ29tcGFyaW5nIHJhdGVzIG9mIGNoYW5nZQpCb3RoIENUbWF4IGFuZCBib2R5IHNpemUgdmFyaWVkIGJldHdlZW4gc2l0ZXMgYW5kIGFjcm9zcyBzZWFzb25zLiBJdCBjYW4gYmUgZGlmZmljdWx0IHRvIGRpcmVjdGx5IGNvbXBhcmUgdGhlc2UgdHdvIHRyYWl0cy4gV2UgdGFrZSB0d28gYXBwcm9hY2hlcyB0byBlYXNlIHRoaXMgY29tcGFyaXNvbi4gCgpTaG93biBiZWxvdyBpcyBhIGNvbXBhcmlzb24gb2YgdGhlIHNsb3BlcyBmcm9tIHRoZSB0cmFpdCByZWdyZXNzaW9ucyBhZ2FpbnN0IGNvbGxlY3Rpb24gdGVtcGVyYXR1cmUgZm9yIGVhY2ggcG9wdWxhdGlvbiwgc3RhbmRhcmRpemVkIGJ5IHRoZSBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIHRyYWl0IGZvciBlYWNoIHBvcHVsYXRpb24gKGFjcm9zcyBhbGwgY29sbGVjdGlvbnMpLiBUaGlzIHN0YW5kYXJkaXplcyB0cmFpdCBjaGFuZ2UgaW4gdW5pdHMgb2Ygc3RhbmRhcmQgZGV2aWF0aW9ucyBwZXIgZGVncmVlIGNoYW5nZSBpbiBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlIGZvciBib3RoIENUbWF4IGFuZCBib2R5IHNpemUuCgpgYGB7ciBhZGotc2xvcGUtY29tcCwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9Nn0KYWRqX3Nsb3BlcyA9IGZ1bGxfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoc2l0ZSwgbGF0KSAlPiUgCiAgYXJyYW5nZShkb3kpICU+JSAgCiAgZmlsdGVyKHNpdGUgIT0gIktleSBMYXJnbyIpICU+JQogIHN1bW1hcml6ZSgiY3RtYXhfc2xvcGUiID0gY29lZihsbShjdG1heCB+IGNvbGxlY3Rpb25fdGVtcCkpWyJjb2xsZWN0aW9uX3RlbXAiXSwgCiAgICAgICAgICAgICJtZWFuX2N0bWF4IiA9IG1lYW4oY3RtYXgpLAogICAgICAgICAgICAiY3RtYXhfc2QiID0gc2QoY3RtYXgpLAogICAgICAgICAgICAic2l6ZV9zbG9wZSIgPSBjb2VmKGxtKHNpemUgfiBjb2xsZWN0aW9uX3RlbXApKVsiY29sbGVjdGlvbl90ZW1wIl0sIAogICAgICAgICAgICAibWVhbl9zaXplIiA9IG1lYW4oc2l6ZSksCiAgICAgICAgICAgICJzaXplX3NkIiA9IHNkKHNpemUpLCAKICAgICAgICAgICAgInRlbXBfcmFuZ2UiID0gbWF4KGNvbGxlY3Rpb25fdGVtcCkgLSBtaW4oY29sbGVjdGlvbl90ZW1wKSkgJT4lICAKICBkcm9wX25hKCkgJT4lIAogIG11dGF0ZShhZGpfY3RtYXhfc2xvcGUgPSBjdG1heF9zbG9wZSAvIGN0bWF4X3NkLAogICAgICAgICBhZGpfc2l6ZV9zbG9wZSA9IHNpemVfc2xvcGUgLyBzaXplX3NkKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjb250YWlucygiX3Nsb3BlIiksIAogICAgICAgICAgICAgICBuYW1lc190byA9ICJzbG9wZV90eXBlIiwKICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInNsb3BlIikKCiMgZ2dwbG90KGFkal9zbG9wZXMsIGFlcyh4ID0gbGF0LCB5ID0gdGVtcF9yYW5nZSkpICsgCiMgICBnZW9tX3BvaW50KCkgKyAKIyAgIHRoZW1lX21hdHQoKQoKZ2dwbG90KGZpbHRlcihhZGpfc2xvcGVzLCBzdHJfZGV0ZWN0KHNsb3BlX3R5cGUsICJhZGpfIikpLCBhZXMoeCA9IHNsb3BlX3R5cGUsIHkgPSBhYnMoc2xvcGUpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSBzaXRlLCBjb2xvdXIgPSBzaXRlKSkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArIAogIGdlb21fbGluZShsaW5ld2lkdGggPSAxKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeCA9ICIiLCAKICAgICAgIHkgPSAiU2xvcGUgKGFic29sdXRlIHZhbHVlKSIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwKICAgICAgICBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDMwMCwgaGp1c3QgPSAwLCB2anVzdCA9IDAuNSkpCmBgYAoKSGFsZGFuZXMgYXJlIGEgc2ltaWxhciB1bml0LCByZXByZXNlbnRpbmcgY2hhbmdlIGluIHVuaXRzIG9mIHN0YW5kYXJkIGRldmlhdGlvbnMgcGVyIGdlbmVyYXRpb24uIFRoaXMgY2FuIGJlIGEgdXNlZnVsIG1ldHJpYyBmb3IgY29tcGFyaW5nIGFjcm9zcyB0cmFpdHMsIGVzcGVjaWFsbHkgYXMgdGhlIG51bWJlciBvZiBnZW5lcmF0aW9ucyBjb3ZlcmVkIGJ5IG91ciBzYW1wbGluZyBwZXJpb2QgbGlrZWx5IHZhcmllcyBhY3Jvc3MgcG9wdWxhdGlvbnMuIFRoZSBjYWxjdWxhdGlvbiBvZiBoYWxkYW5lcyBpcyB0YWtlbiBmcm9tIEhlbmRyeSBhbmQgS2lubmlzb24gKDE5OTkpLCB3aGljaCBpbiB0dXJuIGlzIGJhc2VkIG9uIHdvcmsgZnJvbSBHaW5nZXJpY2ggKDE5OTMpLiBXZSBlc3RpbWF0ZWQgdGhlIG51bWJlciBvZiBnZW5lcmF0aW9ucyBwYXNzZWQgYmV0d2VlbiBjb2xsZWN0aW9ucyB1c2luZyB0aGUgZW1waXJpY2FsIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRlbXBlcmF0dXJlIGFuZCBkZXZlbG9wbWVudCB0aW1lIGZvciAqQWNhcnRpYSB0b25zYSogZnJvbSBMZWFuZHJvIGV0IGFsLiAoMjAwNikuIEZvciBpbml0aWFsIGVzdGltYXRlcywgd2UgdXNlZCBhIHRlbXBlcmF0dXJlIGhhbGZ3YXkgYmV0d2VlbiB3aGF0IHdhcyBvYnNlcnZlZCBkdXJpbmcgY29sbGVjdGlvbiwgYWx0aG91Z2ggdGhpcyBlc3RpbWF0ZSBjYW4gYmUgaW1wcm92ZWQgYnkgdXNpbmcgbm9uLWxpbmVhciBhdmVyYWdpbmcgdG8gYWNjb3VudCBmb3IgSmVuemVuJ3MgSW5lcXVhbGl0eSBhbmQgdGhlIGVmZmVjdCBvZiB0ZW1wZXJhdHVyZSB2YXJpYXRpb24gb24gcmF0ZSBmdW5jdGlvbnMuIENoYW5nZXMgd2VyZSBleGFtaW5lZCBmb3IgZWFjaCBwYWlyIG9mIGNvbGxlY3Rpb25zIChlYXJseSB0byBwZWFrLCBhbmQgcGVhayB0byBsYXRlKS4gICAgCgpTaG93biBiZWxvdyBpcyBhIGNvbXBhcmlzb24gb2YgdGhlIGVzdGltYXRlZCBoYWxkYW5lIHZhbHVlcyBmb3IgQ1RtYXggYW5kIGJvZHkgc2l6ZSwgc2VwYXJhdGVkIGJ5IHNlYXNvbi4gS2VlcCBpbiBtaW5kIHRoYXQgd2hpbGUgdGhpcyBtZXRyaWMgYWNjb3VudHMgZm9yIGRpZmZlcmVuY2VzIGluIHRoZSBudW1iZXIgb2YgZ2VuZXJhdGlvbnMgYmV0d2VlbiBjb2xsZWN0aW9ucywgaXQgZG9lcyBub3QgZGlyZWN0bHkgYWNjb3VudCBmb3IgZGlmZmVyZW5jZXMgaW4gdGVtcGVyYXR1cmUsIGxlYWRpbmcgdG8gaW5mbGF0ZWQgdmFsdWVzIGluIHRoZSAicGVhayB0byBsYXRlIiBjb21wYXJpc29ucywgd2hpY2ggdHlwaWNhbGx5IGNvdmVyZWQgYSBsYXJnZXIgcmFuZ2Ugb2YgdGVtcGVyYXR1cmVzLiAKCmBgYHtyIGhhbGRhbmUtY29tcC1wbG90LCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD0xMn0KZWFybHlfcGVhayA9IGZ1bGxfZGF0YSAlPiUgCiAgZmlsdGVyKHNlYXNvbiAlaW4lIGMoImVhcmx5IiwgInBlYWsiKSkgJT4lIAogIG11dGF0ZShzZWFzb24gPSBpZl9lbHNlKHNlYXNvbiA9PSAiZWFybHkiLCAib25lIiwgInR3byIpKSAlPiUgCiAgZ3JvdXBfYnkoc2l0ZSkgJT4lIAogIG11dGF0ZShjdG1heF9zZF9wID0gc2QoY3RtYXgpLAogICAgICAgICBzaXplX3NkX3AgPSBzZChzaXplKSwgCiAgICAgICAgIHRlbXBfY2hhbmdlID0gbWF4KGNvbGxlY3Rpb25fdGVtcCkgLSBtaW4oY29sbGVjdGlvbl90ZW1wKSwKICAgICAgICAgYXZnX3RlbXAgPSAobWF4KGNvbGxlY3Rpb25fdGVtcCkgKyBtaW4oY29sbGVjdGlvbl90ZW1wKSkgLyAyLAogICAgICAgICBkYXlzX3Bhc3NlZCA9IG1heChkb3kpIC0gbWluKGRveSkpICU+JSAKICBzZWxlY3Qoc2l0ZSwgbGF0LCBzZWFzb24sIAogICAgICAgICBjdG1heF9zZF9wLCBzaXplX3NkX3AsIAogICAgICAgICB0ZW1wX2NoYW5nZSwgYXZnX3RlbXAsIGRheXNfcGFzc2VkLCAKICAgICAgICAgY3RtYXgsIHNpemUpICU+JQogIGdyb3VwX2J5KHNpdGUsIGxhdCwgc2Vhc29uLCAKICAgICAgICAgICBjdG1heF9zZF9wLCBzaXplX3NkX3AsIAogICAgICAgICAgIHRlbXBfY2hhbmdlLCBhdmdfdGVtcCwgZGF5c19wYXNzZWQpICU+JSAKICBzdW1tYXJpemUoY3RtYXggPSBtZWFuKGN0bWF4KSwKICAgICAgICAgICAgc2l6ZSA9IG1lYW4oc2l6ZSkpICU+JSAKICBwaXZvdF93aWRlcihpZF9jb2xzID0gYyhzaXRlLCBsYXQsIGN0bWF4X3NkX3AsIHNpemVfc2RfcCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcF9jaGFuZ2UsIGF2Z190ZW1wLCBkYXlzX3Bhc3NlZCksIAogICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSBzZWFzb24sIAogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gYyhjdG1heCwgc2l6ZSkpICU+JSAKICBtdXRhdGUoc2Vhc29uID0gImVhcmx5X3RvX3BlYWsiKSAlPiUgIAogIGRyb3BfbmEoKQoKcGVha19sYXRlID0gZnVsbF9kYXRhICU+JSAKICBmaWx0ZXIoc2Vhc29uICVpbiUgYygicGVhayIsICJsYXRlIikpICU+JSAKICBtdXRhdGUoc2Vhc29uID0gaWZfZWxzZShzZWFzb24gPT0gInBlYWsiLCAib25lIiwgInR3byIpKSAlPiUgCiAgZ3JvdXBfYnkoc2l0ZSkgJT4lIAogIG11dGF0ZShjdG1heF9zZF9wID0gc2QoY3RtYXgpLAogICAgICAgICBzaXplX3NkX3AgPSBzZChzaXplKSwgCiAgICAgICAgIHRlbXBfY2hhbmdlID0gbGFzdChjb2xsZWN0aW9uX3RlbXApIC0gZmlyc3QoY29sbGVjdGlvbl90ZW1wKSwKICAgICAgICAgYXZnX3RlbXAgPSAobWF4KGNvbGxlY3Rpb25fdGVtcCkgKyBtaW4oY29sbGVjdGlvbl90ZW1wKSkgLyAyLAogICAgICAgICBkYXlzX3Bhc3NlZCA9IG1heChkb3kpIC0gbWluKGRveSkpICU+JSAKICBzZWxlY3Qoc2l0ZSwgbGF0LCBzZWFzb24sIGN0bWF4X3NkX3AsIHNpemVfc2RfcCwgCiAgICAgICAgIHRlbXBfY2hhbmdlLCBhdmdfdGVtcCwgZGF5c19wYXNzZWQsIAogICAgICAgICBjdG1heCwgc2l6ZSkgJT4lCiAgZ3JvdXBfYnkoc2l0ZSwgbGF0LCBzZWFzb24sIGN0bWF4X3NkX3AsIHNpemVfc2RfcCwgCiAgICAgICAgICAgdGVtcF9jaGFuZ2UsIGF2Z190ZW1wLCBkYXlzX3Bhc3NlZCkgJT4lIAogIHN1bW1hcml6ZShjdG1heCA9IG1lYW4oY3RtYXgpLAogICAgICAgICAgICBzaXplID0gbWVhbihzaXplKSkgJT4lIAogIHBpdm90X3dpZGVyKGlkX2NvbHMgPSBjKHNpdGUsIGxhdCwgY3RtYXhfc2RfcCwgc2l6ZV9zZF9wLCAKICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wX2NoYW5nZSwgYXZnX3RlbXAsIGRheXNfcGFzc2VkKSwgCiAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IHNlYXNvbiwgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBjKGN0bWF4LCBzaXplKSkgJT4lIAogIG11dGF0ZShzZWFzb24gPSAicGVha190b19sYXRlIikgJT4lICAKICBkcm9wX25hKCkKCmNhbGNfaGFsZHMgPSBmdW5jdGlvbih4MSwgeDIsIHNkX3AsIGcpewogICgoeDIgLyBzZF9wKSAtICh4MSAvIHNkX3ApKSAvIGcKfQoKaGFsZGFuZXMgPSBiaW5kX3Jvd3MoZWFybHlfcGVhaywgcGVha19sYXRlKSAlPiUgCiAgbXV0YXRlKCJnZW5fdGltZSIgPSA1NDkwKihhdmdfdGVtcCArIDEpXi0yLjA1LCAKICAgICAgICAgImdlbnMiID0gZmxvb3IoZGF5c19wYXNzZWQgLyBnZW5fdGltZSksCiAgICAgICAgICJjdG1heF9oYWxkYW5lcyIgPSBjYWxjX2hhbGRzKHgyID0gY3RtYXhfdHdvLCB4MSA9IGN0bWF4X29uZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNkX3AgPSBjdG1heF9zZF9wLCBnID0gZ2VucyksCiAgICAgICAgICJzaXplX2hhbGRhbmVzIiA9IGNhbGNfaGFsZHMoeDIgPSBzaXplX3R3bywgeDEgPSBzaXplX29uZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2RfcCA9IHNpemVfc2RfcCwgZyA9IGdlbnMpKQoKIyBoYWxkYW5lcyAlPiUgCiMgICB1bmdyb3VwKCkgJT4lIAojICAgc2VsZWN0KHNpdGUsIHRlbXBfY2hhbmdlLCBzZWFzb24sIGN0bWF4X2hhbGRhbmVzLCBzaXplX2hhbGRhbmVzKSAlPiUgCiMgICBwaXZvdF9sb25nZXIoY29scyA9IGMoY3RtYXhfaGFsZGFuZXMsIHNpemVfaGFsZGFuZXMpLAojICAgICAgICAgICAgICAgIG5hbWVzX3RvID0gYygidHlwZSIsIE5BKSwgCiMgICAgICAgICAgICAgICAgbmFtZXNfc2VwID0gIl8iLAojICAgICAgICAgICAgICAgIHZhbHVlc190byA9ICJoYWxkYW5lcyIpICU+JSAKIyAgIGdncGxvdChhZXMoeCA9IHR5cGUsIHkgPSBoYWxkYW5lcywgZ3JvdXAgPSBzaXRlLCBjb2xvdXIgPSBzaXRlKSkgKyAKIyAgIGZhY2V0X3dyYXAoc2Vhc29ufi4pICsgCiMgICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArIAojICAgZ2VvbV9saW5lKGFlcyhsaW5ld2lkdGggPSBkZXNjKHRlbXBfY2hhbmdlKSkpICsgCiMgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKIyAgIGxhYnMoeCA9ICJUcmFpdCIsIAojICAgICAgICB5ID0gIkhhbGRhbmVzIiwgCiMgICAgICAgIGxpbmV3aWR0aCA9ICJUZW1wLiBDaGFuZ2UiKSArIAojICAgdGhlbWVfbWF0dF9mYWNldHMoKQoKY3RtYXhfaGFsZHNfcGxvdCA9IGhhbGRhbmVzICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdChzaXRlLCB0ZW1wX2NoYW5nZSwgc2Vhc29uLCBjdG1heF9oYWxkYW5lcywgc2l6ZV9oYWxkYW5lcykgJT4lICAgCiAgZ2dwbG90KGFlcyh4ID0gc2Vhc29uLCB5ID0gY3RtYXhfaGFsZGFuZXMsIGNvbG91ciA9IHNpdGUsIGdyb3VwID0gc2l0ZSkpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCwgY29sb3VyID0gImdyZXk3MCIpICsgCiAgZ2VvbV9saW5lKGxpbmV3aWR0aCA9IDIpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh4ID0gIlNlYXNvbiIsCiAgICAgICB5ID0gIkhhbGRhbmVzIikgKyAKICBnZ3RpdGxlKCJDVG1heCIpICsgCiAgdGhlbWVfbWF0dCgpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKCnNpemVfaGFsZHNfcGxvdCA9IGhhbGRhbmVzICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdChzaXRlLCB0ZW1wX2NoYW5nZSwgc2Vhc29uLCBjdG1heF9oYWxkYW5lcywgc2l6ZV9oYWxkYW5lcykgJT4lICAgCiAgZ2dwbG90KGFlcyh4ID0gc2Vhc29uLCB5ID0gc2l6ZV9oYWxkYW5lcywgY29sb3VyID0gc2l0ZSwgZ3JvdXAgPSBzaXRlKSkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBjb2xvdXIgPSAiZ3JleTcwIikgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHggPSAiU2Vhc29uIiwKICAgICAgIHkgPSAiSGFsZGFuZXMiKSArIAogIGdndGl0bGUoIlNpemUiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2UoY3RtYXhfaGFsZHNfcGxvdCwgc2l6ZV9oYWxkc19wbG90LCBjb21tb24ubGVnZW5kID0gVCwgbGVnZW5kID0gImJvdHRvbSIpCmBgYAoKYGBge3IgaGFsZGFuZS1yZXNpZHMtY29tcC1wbG90LCBmaWcuaGVpZ2h0PTMuNSwgZmlnLndpZHRoPTksIGluY2x1ZGUgPSBGfQplYXJseV9wZWFrX3Jlc2lkcyA9IHVuaXZlcnNhbF9yZXNpZHMgJT4lIAogIGZpbHRlcihzZWFzb24gJWluJSBjKCJlYXJseSIsICJwZWFrIikpICU+JSAKICBtdXRhdGUoc2Vhc29uID0gaWZfZWxzZShzZWFzb24gPT0gImVhcmx5IiwgIm9uZSIsICJ0d28iKSkgJT4lIAogIGdyb3VwX2J5KHNpdGUpICU+JSAKICBtdXRhdGUoY3RtYXhfc2RfcCA9IHNkKGN0bWF4X3Jlc2lkcyksCiAgICAgICAgIHNpemVfc2RfcCA9IHNkKHNpemVfcmVzaWRzKSwgCiAgICAgICAgIHRlbXBfY2hhbmdlID0gbWF4KGNvbGxlY3Rpb25fdGVtcCkgLSBtaW4oY29sbGVjdGlvbl90ZW1wKSwKICAgICAgICAgYXZnX3RlbXAgPSAobWF4KGNvbGxlY3Rpb25fdGVtcCkgKyBtaW4oY29sbGVjdGlvbl90ZW1wKSkgLyAyLAogICAgICAgICBkYXlzX3Bhc3NlZCA9IG1heChkb3kpIC0gbWluKGRveSkpICU+JSAKICBzZWxlY3Qoc2l0ZSwgbGF0LCBzZWFzb24sIAogICAgICAgICBjdG1heF9zZF9wLCBzaXplX3NkX3AsIAogICAgICAgICB0ZW1wX2NoYW5nZSwgYXZnX3RlbXAsIGRheXNfcGFzc2VkLCAKICAgICAgICAgY3RtYXhfcmVzaWRzLCBzaXplX3Jlc2lkcykgJT4lCiAgZ3JvdXBfYnkoc2l0ZSwgbGF0LCBzZWFzb24sIAogICAgICAgICAgIGN0bWF4X3NkX3AsIHNpemVfc2RfcCwgCiAgICAgICAgICAgdGVtcF9jaGFuZ2UsIGF2Z190ZW1wLCBkYXlzX3Bhc3NlZCkgJT4lIAogIHN1bW1hcml6ZShjdG1heCA9IG1lYW4oY3RtYXhfcmVzaWRzKSwKICAgICAgICAgICAgc2l6ZSA9IG1lYW4oc2l6ZV9yZXNpZHMpKSAlPiUgCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IGMoc2l0ZSwgbGF0LCBjdG1heF9zZF9wLCBzaXplX3NkX3AsIAogICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXBfY2hhbmdlLCBhdmdfdGVtcCwgZGF5c19wYXNzZWQpLCAKICAgICAgICAgICAgICBuYW1lc19mcm9tID0gc2Vhc29uLCAKICAgICAgICAgICAgICB2YWx1ZXNfZnJvbSA9IGMoY3RtYXgsIHNpemUpKSAlPiUgCiAgbXV0YXRlKHNlYXNvbiA9ICJlYXJseV90b19wZWFrIikgJT4lICAKICBkcm9wX25hKCkKCnBlYWtfbGF0ZV9yZXNpZHMgPSB1bml2ZXJzYWxfcmVzaWRzICU+JSAKICBmaWx0ZXIoc2Vhc29uICVpbiUgYygicGVhayIsICJsYXRlIikpICU+JSAKICBtdXRhdGUoc2Vhc29uID0gaWZfZWxzZShzZWFzb24gPT0gInBlYWsiLCAib25lIiwgInR3byIpKSAlPiUgCiAgZ3JvdXBfYnkoc2l0ZSkgJT4lIAogIG11dGF0ZShjdG1heF9zZF9wID0gc2QoY3RtYXhfcmVzaWRzKSwKICAgICAgICAgc2l6ZV9zZF9wID0gc2Qoc2l6ZV9yZXNpZHMpLCAKICAgICAgICAgdGVtcF9jaGFuZ2UgPSBsYXN0KGNvbGxlY3Rpb25fdGVtcCkgLSBmaXJzdChjb2xsZWN0aW9uX3RlbXApLAogICAgICAgICBhdmdfdGVtcCA9IChtYXgoY29sbGVjdGlvbl90ZW1wKSArIG1pbihjb2xsZWN0aW9uX3RlbXApKSAvIDIsCiAgICAgICAgIGRheXNfcGFzc2VkID0gbWF4KGRveSkgLSBtaW4oZG95KSkgJT4lIAogIHNlbGVjdChzaXRlLCBsYXQsIHNlYXNvbiwgY3RtYXhfc2RfcCwgc2l6ZV9zZF9wLCAKICAgICAgICAgdGVtcF9jaGFuZ2UsIGF2Z190ZW1wLCBkYXlzX3Bhc3NlZCwgCiAgICAgICAgIGN0bWF4X3Jlc2lkcywgc2l6ZV9yZXNpZHMpICU+JQogIGdyb3VwX2J5KHNpdGUsIGxhdCwgc2Vhc29uLCBjdG1heF9zZF9wLCBzaXplX3NkX3AsIAogICAgICAgICAgIHRlbXBfY2hhbmdlLCBhdmdfdGVtcCwgZGF5c19wYXNzZWQpICU+JSAKICBzdW1tYXJpemUoY3RtYXggPSBtZWFuKGN0bWF4X3Jlc2lkcyksCiAgICAgICAgICAgIHNpemUgPSBtZWFuKHNpemVfcmVzaWRzKSkgJT4lIAogIHBpdm90X3dpZGVyKGlkX2NvbHMgPSBjKHNpdGUsIGxhdCwgY3RtYXhfc2RfcCwgc2l6ZV9zZF9wLCAKICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wX2NoYW5nZSwgYXZnX3RlbXAsIGRheXNfcGFzc2VkKSwgCiAgICAgICAgICAgICAgbmFtZXNfZnJvbSA9IHNlYXNvbiwgCiAgICAgICAgICAgICAgdmFsdWVzX2Zyb20gPSBjKGN0bWF4LCBzaXplKSkgJT4lIAogIG11dGF0ZShzZWFzb24gPSAicGVha190b19sYXRlIikgJT4lICAKICBkcm9wX25hKCkKCmNhbGNfaGFsZHMgPSBmdW5jdGlvbih4MSwgeDIsIHNkX3AsIGcpewogICgoeDIgLyBzZF9wKSAtICh4MSAvIHNkX3ApKSAvIGcKfQoKaGFsZGFuZXNfcmVzaWRzID0gYmluZF9yb3dzKGVhcmx5X3BlYWtfcmVzaWRzLCBwZWFrX2xhdGVfcmVzaWRzKSAlPiUgCiAgbXV0YXRlKCJnZW5fdGltZSIgPSA1NDkwKihhdmdfdGVtcCArIDEpXi0yLjA1LCAKICAgICAgICAgImdlbnMiID0gZmxvb3IoZGF5c19wYXNzZWQgLyBnZW5fdGltZSksCiAgICAgICAgICJjdG1heF9oYWxkYW5lcyIgPSBjYWxjX2hhbGRzKHgyID0gY3RtYXhfdHdvLCB4MSA9IGN0bWF4X29uZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNkX3AgPSBjdG1heF9zZF9wLCBnID0gZ2VucyksCiAgICAgICAgICJzaXplX2hhbGRhbmVzIiA9IGNhbGNfaGFsZHMoeDIgPSBzaXplX3R3bywgeDEgPSBzaXplX29uZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2RfcCA9IHNpemVfc2RfcCwgZyA9IGdlbnMpKQoKIyBoYWxkYW5lc19yZXNpZHMgJT4lIAojICAgdW5ncm91cCgpICU+JSAKIyAgIHNlbGVjdChzaXRlLCB0ZW1wX2NoYW5nZSwgc2Vhc29uLCBjdG1heF9oYWxkYW5lcywgc2l6ZV9oYWxkYW5lcykgJT4lIAojICAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKGN0bWF4X2hhbGRhbmVzLCBzaXplX2hhbGRhbmVzKSwKIyAgICAgICAgICAgICAgICBuYW1lc190byA9IGMoInR5cGUiLCBOQSksIAojICAgICAgICAgICAgICAgIG5hbWVzX3NlcCA9ICJfIiwKIyAgICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAiaGFsZGFuZXMiKSAlPiUgCiMgICBnZ3Bsb3QoYWVzKHggPSB0eXBlLCB5ID0gaGFsZGFuZXMsIGdyb3VwID0gc2l0ZSwgY29sb3VyID0gc2l0ZSkpICsgCiMgICBmYWNldF93cmFwKHNlYXNvbn4uKSArIAojICAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKyAKIyAgIGdlb21fbGluZShhZXMobGluZXdpZHRoID0gZGVzYyh0ZW1wX2NoYW5nZSkpKSArIAojICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiMgICBsYWJzKHggPSAiVHJhaXQiLCAKIyAgICAgICAgeSA9ICJIYWxkYW5lcyIsIAojICAgICAgICBsaW5ld2lkdGggPSAiVGVtcC4gQ2hhbmdlIikgKyAKIyAgIHRoZW1lX21hdHRfZmFjZXRzKCkKCgpyZXNpZHNfY3RtYXhfaGFsZHNfcGxvdCA9IGhhbGRhbmVzX3Jlc2lkcyAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBzZWxlY3Qoc2l0ZSwgdGVtcF9jaGFuZ2UsIHNlYXNvbiwgY3RtYXhfaGFsZGFuZXMsIHNpemVfaGFsZGFuZXMpICU+JSAgIAogIGdncGxvdChhZXMoeCA9IHNlYXNvbiwgeSA9IGN0bWF4X2hhbGRhbmVzLCBjb2xvdXIgPSBzaXRlLCBncm91cCA9IHNpdGUpKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGNvbG91ciA9ICJncmV5NzAiKSArIAogIGdlb21fbGluZShsaW5ld2lkdGggPSAyKSArIAogIHNjYWxlX2NvbG91cl9tYW51YWwodmFsdWVzID0gc2l0ZV9jb2xzKSArIAogIGxhYnMoeCA9ICJTZWFzb24iLAogICAgICAgeSA9ICJIYWxkYW5lcyIpICsgCiAgZ2d0aXRsZSgiQ1RtYXgiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpyZXNpZHNfc2l6ZV9oYWxkc19wbG90ID0gaGFsZGFuZXNfcmVzaWRzICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIHNlbGVjdChzaXRlLCB0ZW1wX2NoYW5nZSwgc2Vhc29uLCBjdG1heF9oYWxkYW5lcywgc2l6ZV9oYWxkYW5lcykgJT4lICAgCiAgZ2dwbG90KGFlcyh4ID0gc2Vhc29uLCB5ID0gc2l6ZV9oYWxkYW5lcywgY29sb3VyID0gc2l0ZSwgZ3JvdXAgPSBzaXRlKSkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBjb2xvdXIgPSAiZ3JleTcwIikgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMikgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHggPSAiU2Vhc29uIiwKICAgICAgIHkgPSAiSGFsZGFuZXMiKSArIAogIGdndGl0bGUoIlNpemUiKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCgpnZ2FycmFuZ2UocmVzaWRzX2N0bWF4X2hhbGRzX3Bsb3QsIHJlc2lkc19zaXplX2hhbGRzX3Bsb3QsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAiYm90dG9tIikKYGBgCgpgYGB7ciBoYWxkYW5lcy1sYXQtcGxvdCwgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTgsIGluY2x1ZGUgPSBGfQojIFNob3duIGJlbG93IGFyZSB0aGUgaGFsZGFuZSB2YWx1ZXMgcGxvdHRlZCBhZ2FpbnN0IGxhdGl0dWRlLiBOb3RlIHRoYXQgZXZlbiB0aG91Z2ggbGFyZ2UgY2hhbmdlcyBpbiB0ZW1wZXJhdHVyZSBvY2N1cnJlZCBiZXR3ZWVuIHBlYWsgYW5kIGxhdGUgc2FtcGxlcyBpbiB0aGUgQ2hlc2FwZWFrZSwgdGhlIGNoYW5nZSBpbiBoYWxkYW5lcyBpcyByZWxhdGl2ZWx5IHNtYWxsLCB3aGlsZSBpbiB0aGUgTm9ydGhlcm4gcG9wdWxhdGlvbnMsIGNoYW5nZXMgYXJlIGxhcmdlciwgdGhvdWdoIG1vcmUgdmFyaWFibGUuIAoKY3RtYXhfaGFsZGFuZXMgPSBnZ3Bsb3QoaGFsZGFuZXMsIGFlcyh4ID0gbGF0LCB5ID0gY3RtYXhfaGFsZGFuZXMsIGNvbG91ciA9IHNpdGUsIHNoYXBlID0gc2Vhc29uKSkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDMpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh4ID0gIkxhdGl0dWRlIiwKICAgICAgIHkgPSAiQ2hhbmdlIGluIENUbWF4IChoYWxkYW5lcykiKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkKCnNpemVfaGFsZGFuZXMgPSBnZ3Bsb3QoaGFsZGFuZXMsIGFlcyh4ID0gbGF0LCB5ID0gc2l6ZV9oYWxkYW5lcywgY29sb3VyID0gc2l0ZSwgc2hhcGUgPSBzZWFzb24pKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsgCiAgZ2VvbV9wb2ludChzaXplID0gMykgKyAKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IHNpdGVfY29scykgKyAKICBsYWJzKHggPSAiTGF0aXR1ZGUiLAogICAgICAgeSA9ICJDaGFuZ2UgaW4gU2l6ZSAoaGFsZGFuZXMpIikgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpCgpnZ2FycmFuZ2UoY3RtYXhfaGFsZGFuZXMsIHNpemVfaGFsZGFuZXMsIGNvbW1vbi5sZWdlbmQgPSBULCBsZWdlbmQgPSAicmlnaHQiLCBucm93ID0gMikKYGBgCgojIyBXaHkgZG9lcyBpbnRyYXNwZWNpZmljIGRhdGEgbWF0dGVyPyAKClRoZXJtYWwgbGltaXRzIHZhcnkgc3Vic3RhbnRpYWxseSBhY3Jvc3MgYm90aCBzcGF0aWFsIGFuZCB0ZW1wb3JhbCBzY2FsZXMgaW4gdGhpcyBzcGVjaWVzLCBoaWdobGlnaHRpbmcgdGhlIGltcG9ydGFuY2Ugb2YgY29uc2lkZXJpbmcgYm90aCBpbnRyYXNwZWNpZmljIGFuZCB0ZW1wb3JhbCB2YXJpYXRpb24gaW4gdGhlcm1hbCBsaW1pdHMgZm9yIHByZWRpY3Rpb25zIG9mIHZ1bG5lcmFiaWxpdHkgdG8gY2xpbWF0ZSBjaGFuZ2UuIFNpbmdsZSBwb2ludCBlc3RpbWF0ZXMgb2YgdGhlcm1hbCBsaW1pdHMgKGFzIGNvbW1vbmx5IHVzZWQgaW4gbGFyZ2VyLCBnZW5lcmFsIGFuYWx5c2VzIGFjcm9zcyB0YXhhKSBvYnNjdXJlIHRoaXMgY3J1Y2lhbCB2YXJpYXRpb24sIGFuZCBtYXkgYmlhcyBvdXIgZXN0aW1hdGVzIG9mIHNwYXRpYWwgcGF0dGVybnMgaW4gdnVsbmVyYWJpbGl0eS4gSGVyZSB3ZSBleHBsb3JlIHRocmVlIHNlcGFyYXRlIHNjZW5hcmlvcyB0byBpbGx1c3RyYXRlIGFuZCBxdWFudGlmeSB0aGUgaW1wb3J0YW5jZSBvZiB0aGlzIGludHJhc3BlY2lmaWMgdnVsbmVyYWJpbGl0eS4gCgojIyMgU2NlbmFyaW8gMSAtIEludmFyaWFudCB0aGVybWFsIGxpbWl0cwoKVGhlIGZpcnN0IHNjZW5hcmlvIGFzc3VtZXMgdGhhdCB0aGVybWFsIGxpbWl0cyBhcmUgY29uc3RhbnQgYWNyb3NzIGJvdGggc3BhdGlhbCBhbmQgdGVtcG9yYWwgYXhlcyAoaS5lLiBhIHNpbmdsZSBwb2ludCBlc3RpbWF0ZSBvZiB0aGUgdGhlcm1hbCBsaW1pdCBmb3IgdGhpcyBzcGVjaWVzKS4gSGVyZSB3ZSBzZWxlY3RlZCBhIGNlbnRyYWwgcG9wdWxhdGlvbiAodGhlIGhpZ2ggc2FsaW5pdHkgQ2hlc2FwZWFrZSBCYXkgc2l0ZSksIGFuZCB1c2VkIHRoZSBhdmVyYWdlIHRoZXJtYWwgbGltaXQgZnJvbSB0aGUgcGVhayBzZWFzb24gc2FtcGxlIGFzIG91ciAncmVwcmVzZW50YXRpdmUnIHRoZXJtYWwgbGltaXQuIFRoaXMgYXBwcm9hY2ggaXMgc2ltaWxhciB0byB0aGF0IHVzZWQgaW4gQmVubmV0IGV0IGFsLiB0byBjb21waWxlIHRoZSBHbG9iVGhlcm0gZGF0YXNldC4gVGhlc2UgdGhlcm1hbCBsaW1pdHMgYXJlIHVzZWQgdG8gcmUtZXN0aW1hdGUgd2FybWluZyB0b2xlcmFuY2UgZm9yIGVhY2ggY29sbGVjdGlvbiAobWVhbiB0aGVybWFsIGxpbWl0IC0gY29sbGVjdGlvbiB0ZW1wZXJhdHVyZSkuIFdlIHRoZW4gY29tcGFyZWQgdGhpcyBwcmVkaWN0ZWQgd2FybWluZyB0b2xlcmFuY2Ugd2l0aCB0aGUgYWN0dWFsIG9ic2VydmVkIHdhcm1pbmcgdG9sZXJhbmNlcyBmcm9tIGVhY2ggY29sbGVjdGlvbi4gQSBwb3NpdGl2ZSBkaWZmZXJlbmNlIGluZGljYXRlcyBhbiBvdmVyZXN0aW1hdGVkIHdhcm1pbmcgdG9sZXJhbmNlICh0aGUgcG9wdWxhdGlvbiBpcyBhY3R1YWxseSBjbG9zZXIgdG8gdGhlaXIgdGhlcm1hbCBsaW1pdHMgdGhhbiB3b3VsZCBiZSBwcmVkaWN0ZWQgZnJvbSB0aGUgZXN0aW1hdGVkIHZhbHVlLCBhbmQgdGhlcmVmb3JlIG1vcmUgdnVsbmVyYWJsZSkuIEEgbmVnYXRpdmUgZGlmZmVyZW5jZSBpbmRpY2F0ZXMgYW4gdW5kZXJlc3RpbWF0ZWQgd2FybWluZyB0b2xlcmFuY2UgKHRoZSBwb3B1bGF0aW9uIGlzIGZ1cnRoZXIgZnJvbSB0aGVpciB0aGVybWFsIGxpbWl0IHRoYW4gd291bGQgYmUgcHJlZGljdGVkLCBhbmQgdGhlcmVmb3JlIGxlc3MgdnVsbmVyYWJsZSkuIAoKQm90aCBvdmVyZXN0aW1hdGVzIGFuZCB1bmRlcmVzdGltYXRlcyBjYW4gYmUgcHJvYmxlbWF0aWMgZm9yIGFjY3VyYXRlIG1hbmFnZW1lbnQgYW5kIGNvbnNlcnZhdGlvbiBzdHJhdGVnaWVzLiBXZSBzdW1tYXJpemUgZWFjaCBvZiB0aGUgc2NlbmFyaW9zIHVzaW5nIDEpIHRoZSBudW1iZXIgb2YgcG9wdWxhdGlvbnMgd2l0aCBhIGRpZmZlcmVuY2UgYmV0d2VlbiBlc3RpbWF0ZXMgPjLCsEMgaW4gZWl0aGVyIGRpcmVjdGlvbiwgMikgdGhlIGF2ZXJhZ2UgbWFnbml0dWRlIG9mIGRpZmZlcmVuY2UgZm9yIHRoYXQgc3Vic2V0IG9mIHBvcHVsYXRpb25zLCBhbmQgMykgdGhlIHNsb3BlIG9mIHRoZSBkaWZmZXJlbmNlIGFnYWluc3QgbGF0aXR1ZGUuIEVmZmVjdGl2ZSBlc3RpbWF0aW9uIHN0cmF0ZWdpZXMgd2lsbCBoYXZlIGEgc21hbGwgbnVtYmVyIG9mIHBvcHVsYXRpb25zIHdpdGggdW5kZXItIG9yIG92ZXItZXN0aW1hdGVkIHdhcm1pbmcgdG9sZXJhbmNlLCBhIHNtYWxsIG1hZ25pdHVkZSBkaWZmZXJlbmNlIGJldHdlZW4gcHJlZGljdGVkIGFuZCBvYnNlcnZlZCB3YXJtaW5nIHRvbGVyYW5jZSwgYW5kIGEgc2hhbGxvdyBsYXRpdHVkaW5hbCBzbG9wZS4gCgpJbiB0aGlzIGZpcnN0IHNjZW5hcmlvIChzaW5nbGUgcG9pbnQgZXN0aW1hdGUgb2YgdGhlcm1hbCBsaW1pdHMpLCB0aGUgZWZmZWN0aXZlbmVzcyBvZiB0aGUgZXN0aW1hdGUgdmFyaWVkIGFjcm9zcyBsYXRpdHVkZSBhbmQgYWNyb3NzIHNlYXNvbnMuIER1cmluZyB0aGUgZWFybHkgc2Vhc29uLCB0aGVybWFsIGxpbWl0cyBmcm9tIHRoZSBjZW50cmFsIHNpdGUgd2VyZSBhIGRlY2VudCBwcmVkaWN0b3Igb2Ygd2FybWluZyB0b2xlcmFuY2UgYXQgdGhlIG90aGVyIHNpdGVzLCBhbmQgdGhlcmUgd2FzIG9ubHkgYSBzbGlnaHQgbGF0aXR1ZGluYWwgdHJlbmQuIFRoaXMgbGF0aXR1ZGluYWwgdHJlbmQgaW5jcmVhc2VkLCBob3dldmVyLCBkdXJpbmcgdGhlIHBlYWsgYW5kIGxhdGUgc2Vhc29uIGNvbGxlY3Rpb25zLCBkcml2ZW4gYnkgaW5jcmVhc2luZ2x5IGxhcmdlIGRpZmZlcmVuY2VzIGluIHRoZSBub3J0aGVybiBzaXRlcyAoaW5kaWNhdGluZyBpbmNyZWFzZWQgdnVsbmVyYWJpbGl0eSByZWxhdGl2ZSB0byBwcmVkaWN0aW9ucyBpbiB0aGVzZSBzaXRlcykuIER1cmluZyB0aGUgcGVhayBzZWFzb24gY29sbGVjdGlvbiwgd2FybWluZyB0b2xlcmFuY2UgaW4gdGhlIHNvdXRoZXJuIHNpdGVzIHdhcyB1bmRlcmVzdGltYXRlZCBieSBzZXZlcmFsIGRlZ3JlZXMgKHRoZXNlIHBvcHVsYXRpb25zIHdlcmUgbGVzcyB2dWxuZXJhYmxlIHRoYW4gcHJlZGljdGVkIGJ5IHRoZSBjZW50cmFsIHNpdGUgdGhlcm1hbCBsaW1pdHMpLiAKCmBgYHtyfQojIENvbXBhcmUgZXN0aW1hdGVkIHdhcm1pbmcgdG9sZXJhbmNlICJyYW5nZXMiIHdoZW46IDEpIENUbWF4IGZvciAiYXZlcmFnZSIgY29sbGVjdGlvbiBpcyB1c2VkOyAyKSBXaGVuIENUbWF4IGZvciBvbmUgY29sbGVjdGlvbiBwZXIgcG9wdWxhdGlvbiBpcyB1c2VkOyBhbmQgMykgV2hlbiBhbGwgY29sbGVjdGlvbnMgYXJlIHVzZWQuIFRoZSBpZGVhIGlzIHRvIHNob3cgdGhhdCBub3QgYWNjb3VudGluZyBmb3IgaW50cmEtc3BlY2lmaWMgYW5kIGludHJhLXBvcHVsYXRpb24gdmFyaWF0aW9uIGxlYWRzIHRvIGluY29ycmVjdCBwcmVkaWN0aW9ucyBvZiB2dWxuZXJhYmlsaXR5IHRvIHdhcm1pbmcgYmVjYXVzZSB0aGlzIHZhcmlhdGlvbiBjYW4gYmUgc3Vic3RhbnRpYWwgLSBhY3Jvc3MgcG9wdWxhdGlvbnMgd2l0aGluIGVhY2ggc2Vhc29uYWwgY29sbGVjdGlvbiwgdGhlcmUgaXMgYXQgbGVhc3QgNcKwQyB2YXJpYXRpb24gaW4gdGhlcm1hbCBsaW1pdHMsIHdoaWxlIGFjcm9zcyBjb2xsZWN0aW9ucyB3aXRoaW4gcG9wdWxhdGlvbnMsIGFjY2xpbWF0aW9uIHRvIGNoYW5nZXMgaW4gdGVtcGVyYXR1cmUgY2FuIGRyaXZlIHN1YnN0YW50aWFsIHZhcmlhdGlvbi4gCgojIyBTY2VuYXJpbyAxIC0gc2luZ2xlIHBvaW50IGVzdGltYXRlcyAKCmVzdF8xID0gZnVsbF9kYXRhICU+JSAKICBncm91cF9ieShzaXRlLCBzZWFzb24pICU+JSAKICBzdW1tYXJpc2UoIm1lYW5fY3RtYXgiID0gbWVhbihjdG1heCkpICU+JSAKICBmaWx0ZXIoc2l0ZSA9PSAiVHlsZXIgQ292ZSIsIHNlYXNvbiA9PSAicGVhayIpCgpzY2VuYXJpb18xID0gZnVsbF9kYXRhICU+JSAKICBtdXRhdGUocmVwX2N0bWF4ID0gZXN0XzEkbWVhbl9jdG1heCwKICAgICAgICAgcHJlZF93dCA9IHJlcF9jdG1heCAtIGNvbGxlY3Rpb25fdGVtcCwgCiAgICAgICAgIHd0X2RpZmYgPSBwcmVkX3d0IC0gd2FybWluZ190b2wpCgpnZ3Bsb3Qoc2NlbmFyaW9fMSwgYWVzKHggPSBsYXQsIHkgPSB3dF9kaWZmKSkgKyAKICBmYWNldF93cmFwKHNlYXNvbn4uLCBucm93ID0gMykgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgbGFicyh4ID0gIkxhdGl0dWRlIiwgCiAgICAgICB5ID0gIlByZWRpY3RlZCAtIE9ic2VydmVkIFdUIikgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpCgpsYXQubW9kZWwxID0gbG0oZGF0YSA9IHNjZW5hcmlvXzEsCiAgICAgICAgICAgICAgICB3dF9kaWZmIH4gbGF0KnNlYXNvbikKCmxhdF9zbG9wZV8xID0gZW1tZWFuczo6ZW10cmVuZHMobGF0Lm1vZGVsMSwgdmFyID0gImxhdCIsIHNwZWNzID0gInNlYXNvbiIpICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIHNlbGVjdChzZWFzb24sIGxhdC50cmVuZCkKCnBlcmZvcm1hbmNlXzEgPSBzY2VuYXJpb18xICU+JSAKICBzZWxlY3Qoc2l0ZSwgbGF0LCBzZWFzb24sIHd0X2RpZmYpICU+JSAgCiAgZ3JvdXBfYnkoc2l0ZSwgc2Vhc29uLCBsYXQpICU+JSAKICBzdW1tYXJpc2UoIm1lYW5fZGlmZiIgPSBtZWFuKHd0X2RpZmYpLAogICAgICAgICAgICAiYWJzX2RpZmYiID0gYWJzKG1lYW5fZGlmZikpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIG11dGF0ZSgiZmxhZyIgPSBpZl9lbHNlKGFic19kaWZmID49IDIsICJ5ZXMiLCAibm8iKSkgJT4lIAogIGZpbHRlcihmbGFnID09ICJ5ZXMiKSAlPiUgIAogIGdyb3VwX2J5KHNlYXNvbikgJT4lIAogIHN1bW1hcmlzZSgiYXZnX2RpZmYiID0gbWVhbihhYnNfZGlmZiksCiAgICAgICAgICAgICJuIiA9IG4oKSkgJT4lIAogIGlubmVyX2pvaW4obGF0X3Nsb3BlXzEsIGJ5ID0gInNlYXNvbiIpCmBgYAoKIyMjIFNjZW5hcmlvIDIgLSBTZWFzb25hbGx5IGludmFyaWFudCB0aGVybWFsIGxpbWl0cwoKTG9jYWwgYWRhcHRhdGlvbiBvZiB0aGVybWFsIGxpbWl0cyBpcyB3aWRlbHkgb2JzZXJ2ZWQgYWNyb3NzIGEgcmFuZ2Ugb2YgdGF4YSwgaW5jbHVkaW5nICpBY2FydGlhIHRvbnNhKi4gSW4gdGhlIHNlY29uZCBzY2VuYXJpbywgd2UgYWNjb3VudCBmb3IgdGhpcyBieSB1c2luZyBhdmVyYWdlIHRoZXJtYWwgbGltaXRzIGZyb20gdGhlIHBlYWsgc2Vhc29uIGZvciBlYWNoIHBvcHVsYXRpb24gaW4gdGhlIGVzdGltYXRlcyBvZiB3YXJtaW5nIHRvbGVyYW5jZSB0aHJvdWdob3V0IHRoZSB5ZWFyLiAKClVuc3VycHJpc2luZ2x5LCB0aGlzIGFwcHJvYWNoIGVsaW1pbmF0ZXMgdGhlIGxhdGl0dWRpbmFsIHRyZW5kLiBJbnN0ZWFkIHdlIHNlZSB0aGF0IHBlYWsgc2Vhc29uIGVzdGltYXRlcyB3ZXJlIGdlbmVyYWxseSBkZWNlbnQgcHJlZGljdG9ycyBvZiB3YXJtaW5nIHRvbGVyYW5jZSBkdXJpbmcgdGhlIGVhcmx5IHNlYXNvbiAoYWx0aG91Z2ggdGhlcmUgd2VyZSBzbGlnaHQgb3ZlcmVzdGltYXRlcyBpbiBzZXZlcmFsIHBvcHVsYXRpb25zKSwgYW5kIHNsaWdodGx5IHVuZGVyZXN0aW1hdGVkIHdhcm1pbmcgdG9sZXJhbmNlIGR1cmluZyB0aGUgbGF0ZSBzZWFzb24uCgpgYGB7cn0KZXN0XzIgPSBmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHNpdGUsIHNlYXNvbikgJT4lIAogIHN1bW1hcmlzZSgibWVhbl9jdG1heCIgPSBtZWFuKGN0bWF4KSkgJT4lIAogIGZpbHRlcihzZWFzb24gPT0gInBlYWsiKSAlPiUgCiAgc2VsZWN0KHNpdGUsIG1lYW5fY3RtYXgpCgpzY2VuYXJpb18yID0gZnVsbF9kYXRhICU+JSAKICBpbm5lcl9qb2luKGVzdF8yLCBieSA9IGMoInNpdGUiKSkgJT4lIAogIG11dGF0ZShwcmVkX3d0ID0gbWVhbl9jdG1heCAtIGNvbGxlY3Rpb25fdGVtcCwgCiAgICAgICAgIHd0X2RpZmYgPSBwcmVkX3d0IC0gd2FybWluZ190b2wpCgpnZ3Bsb3Qoc2NlbmFyaW9fMiwgYWVzKHggPSBsYXQsIHkgPSB3dF9kaWZmKSkgKyAKICBmYWNldF93cmFwKHNlYXNvbn4uLCBucm93ID0gMykgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgbGFicyh4ID0gIkxhdGl0dWRlIiwgCiAgICAgICB5ID0gIlByZWRpY3RlZCAtIE9ic2VydmVkIFdUIikgKyAKICB0aGVtZV9tYXR0X2ZhY2V0cygpCgpsYXQubW9kZWwyID0gbG0oZGF0YSA9IHNjZW5hcmlvXzIsCiAgICAgICAgICAgICAgICB3dF9kaWZmIH4gbGF0KnNlYXNvbikKCmxhdF9zbG9wZV8yID0gZW1tZWFuczo6ZW10cmVuZHMobGF0Lm1vZGVsMiwgdmFyID0gImxhdCIsIHNwZWNzID0gInNlYXNvbiIpICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIHNlbGVjdChzZWFzb24sIGxhdC50cmVuZCkKCnBlcmZvcm1hbmNlXzIgPSBzY2VuYXJpb18yICU+JSAKICBzZWxlY3Qoc2l0ZSwgbGF0LCBzZWFzb24sIHd0X2RpZmYpICU+JSAgCiAgZ3JvdXBfYnkoc2l0ZSwgc2Vhc29uLCBsYXQpICU+JSAKICBzdW1tYXJpc2UoIm1lYW5fZGlmZiIgPSBtZWFuKHd0X2RpZmYpLAogICAgICAgICAgICAiYWJzX2RpZmYiID0gYWJzKG1lYW5fZGlmZikpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIG11dGF0ZSgiZmxhZyIgPSBpZl9lbHNlKGFic19kaWZmID49IDIsICJ5ZXMiLCAibm8iKSkgJT4lIAogIGZpbHRlcihmbGFnID09ICJ5ZXMiKSAlPiUgIAogIGdyb3VwX2J5KHNlYXNvbikgJT4lIAogIHN1bW1hcmlzZSgiYXZnX2RpZmYiID0gbWVhbihhYnNfZGlmZiksCiAgICAgICAgICAgICJuIiA9IG4oKSkgJT4lICAKICBpbm5lcl9qb2luKGxhdF9zbG9wZV8yLCBieSA9IGMoInNlYXNvbiIpKQpgYGAKCiMjIyBTY2VuYXJpbyAzIC0gUG9wdWxhdGlvbiBzdWItc2FtcGxpbmcgCgpCb3RoIG9mIHRoZSBwcmV2aW91cyBhcHByb2FjaGVzIHRvIGVzdGltYXRpbmcgd2FybWluZyB0b2xlcmFuY2UgcmVzdWx0IGluIG92ZXJlc3RpbWF0ZXMgb2Ygd2FybWluZyB0b2xlcmFuY2UuIFRoZXNlIHJlZHVjdGl2ZSBtZXRob2RzIGluY3JlYXNlIHRoZSBmZWFzaWJpbGl0eSwgYnV0IGFyZSB1bmFibGUgdG8gYWNjb3VudCBmb3IgdGhlIGNvLW9jY3VyaW5nIHNoaWZ0cyBpbiBhbWJpZW50IHRlbXBlcmF0dXJlIGFuZCB0aGVybWFsIGxpbWl0cy4gQ29udGludW91cyBpbi1zaXR1IG1vbml0b3Jpbmcgb2YgdGhlcm1hbCBsaW1pdHMgaXMgaW1wcmFjdGljYWwsIGhvd2V2ZXIsIGVzcGVjaWFsbHkgZm9yIHNwZWNpZXMgd2l0aCBzbWFsbCBwb3B1YXRpb24gc2l6ZXMgYW5kL29yIHZlcnkgbGFyZ2UgcmFuZ2UgZGlzdHJpYnV0aW9ucy4gT25lIHBvdGVudGlhbCBjb21wcm9taXNlIHNvbHV0aW9uIGlzIHRvIHN1Yi1zYW1wbGUgcG9wdWxhdGlvbnMgYW5kIHVzZSBvYnNlcnZlZCBkYXRhIHRvIHByZWRpY3Qgc3BhdGlhbCBhbmQgc2Vhc29uYWwgY2hhbmdlcyBpbiB3YXJtaW5nIHRvbGVyYW5jZS4gCgpJbiB0aGlzIHRoaXJkIGFwcHJvYWNoLCB3ZSByYW5kb21seSBzZWxlY3RlZCBuaW5lIGNvbGxlY3Rpb25zLCBmaXQgYSBsaW5lYXIgbW9kZWwgb2YgQ1RtYXggfiBjb2xsZWN0aW9uIHRlbXBlcmF0dXJlLCBhbmQgdXNlZCB0aGlzIHJlZ3Jlc3Npb24gdG8gcHJlZGljdCB0aGVybWFsIGxpbWl0cyBhbmQgd2FybWluZyB0b2xlcmFuY2UgYWNyb3NzIHRoZSBmdWxsIHNldCBvZiBjb2xsZWN0aW9ucy4gVGhlc2UgcHJlZGljdGVkIHdhcm1pbmcgdG9sZXJhbmNlIHZhbHVlcyB3ZXJlIHRoZW4gY29tcGFyZWQgYWdhaW5zdCBvYnNlcnZlZCB3YXJtaW5nIHRvbGVyYW5jZSBhcyBiZWZvcmUuIFdlIHJlcGVhdGVkIHRoaXMgcHJvY2VzcyAxMDAgdGltZXMgKDEwMCByYW5kb20gc2V0cyBvZiA5IGNvbGxlY3Rpb25zKSB0byBleGFtaW5lIHRoZSBzZW5zaXRpdml0eSBvZiB0aGlzIGFwcHJvYWNoIHRoZSBwb3B1bGF0aW9ucyBhbmQgc2Vhc29ucyBjb2xsZWN0ZWQuIEluIGFkZGl0aW9uIHRvIHRoaXMgcmFuZG9tIGRhdGEsIHdlIGFsc28gaW5jbHVkZWQgYSBzY2VuYXJpbyB3aGVyZSBhbGwgc2Vhc29uYWwgY29sbGVjdGlvbnMgZnJvbSBGdC4gSGFtZXIsIFR5bGVyIENvdmUsIGFuZCBNaXJhbWljaGkgKHRoZSBsYXRpdHVkaW5hbCBleHRyZW1lcyBhbmQgYSBjZW50cmFsIHBvaW50KSB3ZXJlIHVzZWQgdG8gcHJlZGljdCB0aGVybWFsIGxpbWl0cy4gCgpgYGB7cn0KCnNjZW5hcmlvXzMgPSBkYXRhLmZyYW1lKCkKcGVyZm9ybWFuY2VfMyA9IGRhdGEuZnJhbWUoKQoKZm9yKGkgaW4gMToxMDApewogIAogIGVzdF8zID0gZnVsbF9kYXRhICU+JSAKICAgIGdyb3VwX2J5KHNpdGUsIHNlYXNvbiwgY29sbGVjdGlvbl90ZW1wKSAlPiUgCiAgICBzdW1tYXJpc2UoIm1lYW5fY3RtYXgiID0gbWVhbihjdG1heCksIC5ncm91cHMgPSAia2VlcCIpICU+JSAKICAgIHVuZ3JvdXAoKSAlPiUgCiAgICBmaWx0ZXIocm93X251bWJlcigpICVpbiUgc2FtcGxlKGMoMTptYXgocm93X251bWJlcigpKSksIHNpemUgPSA5LCByZXBsYWNlID0gRikpCiAgCiAgcmVwLm1vZGVsID0gbG0oZGF0YSA9IGVzdF8zLCBtZWFuX2N0bWF4IH4gY29sbGVjdGlvbl90ZW1wKQogIAogIHJlcF9kYXRhID0gZnVsbF9kYXRhICU+JSAKICAgIGdyb3VwX2J5KHNpdGUsIHNlYXNvbikgJT4lICAKICAgIG11dGF0ZShtZWFuX3d0ID0gbWVhbih3YXJtaW5nX3RvbCkpICU+JSAKICAgIHNlbGVjdChzaXRlLCBzZWFzb24sIGNvbGxlY3Rpb25fdGVtcCwgbGF0LCBtZWFuX3d0KSAlPiUgCiAgICB1bmdyb3VwKCkgJT4lIAogICAgZGlzdGluY3QoKSAlPiUgIAogICAgbXV0YXRlKHByZWRfY3RtYXggPSBwcmVkaWN0KHJlcC5tb2RlbCwgbmV3ZGF0YSA9IC4pLAogICAgICAgICAgIHByZWRfd3QgPSBwcmVkX2N0bWF4IC0gY29sbGVjdGlvbl90ZW1wLAogICAgICAgICAgIHd0X2RpZmYgPSBwcmVkX3d0IC0gbWVhbl93dCwKICAgICAgICAgICBydW4gPSBpLAogICAgICAgICAgIGdyb3VwID0gInJhbmRvbSIpCiAgCiAgc2NlbmFyaW9fMyA9IGJpbmRfcm93cyhzY2VuYXJpb18zLCByZXBfZGF0YSkKICAKICBsYXQubW9kZWwzID0gbG0oZGF0YSA9IHNjZW5hcmlvXzMsCiAgICAgICAgICAgICAgICAgIHd0X2RpZmYgfiBsYXQqc2Vhc29uKQogIAogIGxhdF9zbG9wZV8zID0gZW1tZWFuczo6ZW10cmVuZHMobGF0Lm1vZGVsMywgdmFyID0gImxhdCIsIHNwZWNzID0gInNlYXNvbiIpICU+JSAKICAgIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgICBzZWxlY3Qoc2Vhc29uLCBsYXQudHJlbmQpCiAgCiAgcmVwX3BlcmZvcm1hbmNlID0gc2NlbmFyaW9fMyAlPiUgCiAgICBzZWxlY3Qoc2l0ZSwgbGF0LCBzZWFzb24sIHd0X2RpZmYpICU+JSAgCiAgICBncm91cF9ieShzaXRlLCBzZWFzb24sIGxhdCkgJT4lIAogICAgc3VtbWFyaXNlKCJtZWFuX2RpZmYiID0gbWVhbih3dF9kaWZmKSwKICAgICAgICAgICAgICAiYWJzX2RpZmYiID0gYWJzKG1lYW5fZGlmZiksIAogICAgICAgICAgICAgIC5ncm91cHMgPSAia2VlcCIpICU+JSAKICAgIHVuZ3JvdXAoKSAlPiUgCiAgICBtdXRhdGUoImZsYWciID0gaWZfZWxzZShhYnNfZGlmZiA+PSAyLCAieWVzIiwgIm5vIikpICU+JSAKICAgIGZpbHRlcihmbGFnID09ICJ5ZXMiKSAlPiUgIAogICAgZ3JvdXBfYnkoc2Vhc29uKSAlPiUgCiAgICBzdW1tYXJpc2UoImF2Z19kaWZmIiA9IG1lYW4oYWJzX2RpZmYpLAogICAgICAgICAgICAgICJuIiA9IG4oKSwKICAgICAgICAgICAgICAuZ3JvdXBzID0gImtlZXAiKSAlPiUgIAogICAgaW5uZXJfam9pbihsYXRfc2xvcGVfMywgYnkgPSBjKCJzZWFzb24iKSkKICAKICBwZXJmb3JtYW5jZV8zID0gYmluZF9yb3dzKHBlcmZvcm1hbmNlXzMsIHJlcF9wZXJmb3JtYW5jZSkKICAKfQoKZ29sZF9zdGFuZCA9IGZ1bGxfZGF0YSAlPiUgCiAgZ3JvdXBfYnkoc2l0ZSwgc2Vhc29uLCBjb2xsZWN0aW9uX3RlbXApICU+JSAKICBzdW1tYXJpc2UoIm1lYW5fY3RtYXgiID0gbWVhbihjdG1heCksIC5ncm91cHMgPSAia2VlcCIpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGZpbHRlcihzaXRlICVpbiUgYygiRnQuIEhhbWVyIiwgIlR5bGVyIENvdmUiLCAiTWlyYW1pY2hpIikpCgpnb2xkLm1vZGVsID0gbG0oZGF0YSA9IGdvbGRfc3RhbmQsIG1lYW5fY3RtYXggfiBjb2xsZWN0aW9uX3RlbXApCgpnb2xkX2RhdGEgPSBmdWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHNpdGUsIHNlYXNvbikgJT4lICAKICBtdXRhdGUobWVhbl93dCA9IG1lYW4od2FybWluZ190b2wpKSAlPiUgCiAgc2VsZWN0KHNpdGUsIHNlYXNvbiwgY29sbGVjdGlvbl90ZW1wLCBsYXQsIG1lYW5fd3QpICU+JSAKICB1bmdyb3VwKCkgJT4lIAogIGRpc3RpbmN0KCkgJT4lICAKICBtdXRhdGUocHJlZF9jdG1heCA9IHByZWRpY3QoZ29sZC5tb2RlbCwgbmV3ZGF0YSA9IC4pLAogICAgICAgICBwcmVkX3d0ID0gcHJlZF9jdG1heCAtIGNvbGxlY3Rpb25fdGVtcCwKICAgICAgICAgd3RfZGlmZiA9IHByZWRfd3QgLSBtZWFuX3d0LAogICAgICAgICBydW4gPSBpICsgMSwKICAgICAgICAgZ3JvdXAgPSAiZ29sZCIpCgpnb2xkLm1vZGVsID0gbG0oZGF0YSA9IGdvbGRfZGF0YSwKICAgICAgICAgICAgICAgIHd0X2RpZmYgfiBsYXQqc2Vhc29uKQoKZ29sZF9zbG9wZSA9IGVtbWVhbnM6OmVtdHJlbmRzKGdvbGQubW9kZWwsIHZhciA9ICJsYXQiLCBzcGVjcyA9ICJzZWFzb24iKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICBzZWxlY3Qoc2Vhc29uLCBsYXQudHJlbmQpCgpnb2xkX3BlcmZvcm1hbmNlID0gZ29sZF9kYXRhICU+JSAKICBzZWxlY3Qoc2l0ZSwgbGF0LCBzZWFzb24sIHd0X2RpZmYpICU+JSAgCiAgZ3JvdXBfYnkoc2l0ZSwgc2Vhc29uLCBsYXQpICU+JSAKICBzdW1tYXJpc2UoIm1lYW5fZGlmZiIgPSBtZWFuKHd0X2RpZmYpLAogICAgICAgICAgICAiYWJzX2RpZmYiID0gYWJzKG1lYW5fZGlmZiksIAogICAgICAgICAgICAuZ3JvdXBzID0gImtlZXAiKSAlPiUgCiAgdW5ncm91cCgpICU+JSAKICBtdXRhdGUoImZsYWciID0gaWZfZWxzZShhYnNfZGlmZiA+PSAyLCAieWVzIiwgIm5vIikpICU+JSAKICBmaWx0ZXIoZmxhZyA9PSAieWVzIikgJT4lICAKICBncm91cF9ieShzZWFzb24pICU+JSAKICBzdW1tYXJpc2UoImF2Z19kaWZmIiA9IG1lYW4oYWJzX2RpZmYpLAogICAgICAgICAgICAibiIgPSBuKCksCiAgICAgICAgICAgIC5ncm91cHMgPSAia2VlcCIpICU+JSAgCiAgaW5uZXJfam9pbihnb2xkX3Nsb3BlLCBieSA9IGMoInNlYXNvbiIpKQoKc2NlbmFyaW9fMyA9IGJpbmRfcm93cyhzY2VuYXJpb18zLCBnb2xkX2RhdGEpCgpwZXJmb3JtYW5jZV8zX3N1bSA9IHBlcmZvcm1hbmNlXzMgJT4lICAKICBncm91cF9ieShzZWFzb24pICU+JSAgCiAgc3VtbWFyaXNlKCJhdmdfZGlmZiIgPSBtZWFuKGF2Z19kaWZmKSwKICAgICAgICAgICAgIm4iID0gbWVhbihuKSwKICAgICAgICAgICAgImxhdC50cmVuZCIgPSBtZWFuKGxhdC50cmVuZCkpCgpnZ3Bsb3Qoc2NlbmFyaW9fMywgYWVzKHggPSBsYXQsIHkgPSB3dF9kaWZmLCBjb2xvdXIgPSBncm91cCwgZ3JvdXAgPSBydW4pKSArIAogIGZhY2V0X3dyYXAoc2Vhc29ufi4sIG5yb3cgPSAzKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsgCiAgZ2VvbV9zbW9vdGgoYWVzKGNvbG91ciA9IGdyb3VwKSwgCiAgICAgICAgICAgICAgbWV0aG9kID0gImxtIiwgc2UgPSBGKSArIAogIGdlb21fcG9pbnQoKSArIAogIGxhYnMoeCA9ICJMYXRpdHVkZSIsIAogICAgICAgeSA9ICJQcmVkaWN0ZWQgLSBPYnNlcnZlZCBXVCIpICsgCiAgdGhlbWVfbWF0dF9mYWNldHMoKQoKYGBgCgpgYGB7cn0Ka25pdHI6OmthYmxlKHBlcmZvcm1hbmNlXzEsIGNhcHRpb24gPSAiU2NlbmFyaW8gMSIpCgprbml0cjo6a2FibGUocGVyZm9ybWFuY2VfMiwgY2FwdGlvbiA9ICJTY2VuYXJpbyAyIikKCmtuaXRyOjprYWJsZShwZXJmb3JtYW5jZV8zX3N1bSwgY2FwdGlvbiA9ICJTY2VuYXJpbyAzIikKCmtuaXRyOjprYWJsZShnb2xkX3BlcmZvcm1hbmNlLCBjYXB0aW9uID0gImBHb2xkYCBTdGFuZGFyZCIpCmBgYAoKYGBge3J9CmJlc3QgPSBiaW5kX3Jvd3MoCiAgbXV0YXRlKHBlcmZvcm1hbmNlXzEsICJzY2VuYXJpbyIgPSAib25lIiksCiAgbXV0YXRlKHBlcmZvcm1hbmNlXzIsICJzY2VuYXJpbyIgPSAidHdvIiksCiAgbXV0YXRlKHBlcmZvcm1hbmNlXzNfc3VtLCAic2NlbmFyaW8iID0gInRocmVlIiksCiAgbXV0YXRlKGdvbGRfcGVyZm9ybWFuY2UsICJzY2VuYXJpbyIgPSAiZ29sZCIpKSAlPiUgCiAgZ3JvdXBfYnkoc2Vhc29uKSAlPiUgIAogIGZpbHRlcihhYnMobGF0LnRyZW5kKSA9PSBtaW4oYWJzKGxhdC50cmVuZCkpKQojZmlsdGVyKGF2Z19kaWZmID09IG1pbihhdmdfZGlmZikpCmBgYAoKCiMjIE5leHQgU3RlcHMKCkFmdGVyIHBoZW5vdHlwaW5nLCBlYWNoIGluZGl2aWR1YWwgd2FzIHByZXNlcnZlZCBpbiA5NSUgZXRoYW5vbC4gSW5kaXZpZHVhbCBETkEgbGlicmFyaWVzIHdpbGwgYmUgcHJlcGFyZWQgdXNpbmcgVHdpc3QgQmlvIDk2LXBsZXggcHJlcCBraXRzLCB0aGVuIHNlcXVlbmNlZCBvbiBhbiBJbGx1bWluYSBOb3ZhU2VxIFggUGx1cy4gVXNpbmcgdGhlIGxvdy1jb3ZlcmFnZSB3aG9sZSBnZW5vbWUgc2VxdWVuY2VzLCB3ZSB3aWxsIGV4YW1pbmUgc2Vhc29uYWwgcGF0dGVybnMgaW4gYWxsZWxlIGZyZXF1ZW5jeSBjaGFuZ2UsIGFuZCBjb21wYXJlIHRoZXNlIGZpbmUgc2NhbGUgdGVtcG9yYWwgcGF0dGVybnMgd2l0aCB0aGUgbGFyZ2VyIGxhdGl0dWRpbmFsIHBhdHRlcm5zIGluIGFsbGVsZSBmcmVxdWVuY3kgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIHNhbWUgYWxsZWxlcyBkcml2aW5nIHJhcGlkIHNlYXNvbmFsIGFkYXB0YXRpb24gYXJlIGluIHBsYXkgb3ZlciBsYXJnZXIgc3BhdGlhbCAoYW5kIGxvbmdlciB0ZW1wb3JhbCkgc2NhbGVzLgoKIyMgTWlzYy4gRGV0YWlscwoKYGBge3IgdGVtcC1yZWNvcmQtcGxvdCwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Nn0KZ2dwbG90KHRlbXBfcmVjb3JkLCBhZXMoeCA9IG1pbnV0ZV9wYXNzZWQsIHkgPSB0ZW1wX0MsIGdyb3VwID0gZmFjdG9yKHJ1bikpKSArIAogIGdlb21fYWJsaW5lKHNsb3BlID0gMC4zLCBpbnRlcmNlcHQgPSBtZWFuKHRlbXBfcmVjb3JkW3RlbXBfcmVjb3JkJG1pbnV0ZV9pbnRlcnZhbCA9PSAwLCA4XSkpICsgCiAgZ2VvbV9hYmxpbmUoc2xvcGUgPSAwLjEsIGludGVyY2VwdCA9IG1lYW4odGVtcF9yZWNvcmRbdGVtcF9yZWNvcmQkbWludXRlX2ludGVydmFsID09IDAsIDhdKSkgKyAKICBnZW9tX2xpbmUobGluZXdpZHRoID0gMC4yLCBhbHBoYSA9IDAuOCkgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBmdWxsX2RhdGEsIAogICAgICAgICAgICAgYWVzKHggPSB0aW1lLCB5ID0gY3RtYXggKyAwLjQpLAogICAgICAgICAgICAgc2l6ZSA9IDIsCiAgICAgICAgICAgICBzaGFwZSA9IDI1KSArCiAgbGFicyh4ID0gIlRpbWUgcGFzc2VkIChtaW51dGVzKSIsCiAgICAgICB5ID0gIlRlbXBlcmF0dXJlIChkZWdyZWVzIEMpIiwKICAgICAgIGZpbGwgPSAiVHJpYWwgTnVtYmVyIikgKyAKICBndWlkZXMoY29sb3VyID0gIm5vbmUiKSArIAogIHRoZW1lX21hdHQoYmFzZV9zaXplID0gMTYpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikKYGBgCgpgYGB7ciByYW1wLXJlY29yZC1wbG90LCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD02fQpyYW1wX3JlY29yZDIgPSByYW1wX3JlY29yZCAlPiUgCiAgZ3JvdXBfYnkocnVuLCBtaW51dGVfaW50ZXJ2YWwpICU+JSAKICBzdW1tYXJpc2UobWVhbl9yYW1wID0gbWVhbihyYW1wX3Blcl9taW51dGUpKSAlPiUgCiAgdW5ncm91cCgpCgpnZ3Bsb3QocmFtcF9yZWNvcmQyLCBhZXMoeCA9IG1pbnV0ZV9pbnRlcnZhbCwgeSA9IG1lYW5fcmFtcCkpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMC4zKSArIAogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAuMSkgKyAKICAjZ2VvbV9wb2ludCgpICsgCiAgZ2VvbV9oZXgoYmlucyA9IDMwKSArIAogIHlsaW0oMCwgMC4zNSkgKyAKICBsYWJzKHkgPSAiUmFtcCBSYXRlIChkZWcuIEMgLyBtaW4uKSIsCiAgICAgICB4ID0gIlRpbWUgaW50byBydW4gKG1pbnV0ZSkiKSArIAogIHRoZW1lX21hdHQoYmFzZV9zaXplID0gMTYpIApgYGAKCmBgYHtyIHJlcC1jb21wLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9OH0KZnVsbF9kYXRhICU+JSAKICBkcm9wX25hKHJlcGxpY2F0ZSkgJT4lICAKICBnZ3Bsb3QoYWVzKHggPSBmYWN0b3IocmVwbGljYXRlKSwgeSA9IGN0bWF4LCBncm91cCA9IHNpdGUpKSArIAogIGZhY2V0X2dyaWQoc2l0ZX5zZWFzb24sIHNjYWxlcyA9ICJmcmVlX3kiKSArIAogIGdlb21fcG9pbnQocG9zaXRpb24gPSBwb3NpdGlvbl9qaXR0ZXIod2lkdGggPSAwLjEsIGhlaWdodCA9IDApLAogICAgICAgICAgICAgYWxwaGEgPSAwLjQsCiAgICAgICAgICAgICBjb2xvdXIgPSAiZ3JleTMwIikgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBjb2xvdXIgPSAiYmxhY2siKSArIAogIGxhYnMoeCA9ICJSZXBsaWNhdGUiLCAKICAgICAgIHkgPSAiQ1RtYXgiKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkKYGBgCgpgYGB7ciBudW0tZ2Vucy1wbG90LCBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9N30KZ2dwbG90KGhhbGRhbmVzLCBhZXMoeCA9IGxhdCwgeSA9IGdlbnMsIGNvbG91ciA9IHNpdGUsIHNoYXBlID0gc2Vhc29uKSkgKyAKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxKSArIAogIGdlb21fcG9pbnQoc2l6ZSA9IDUpICsgCiAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBzaXRlX2NvbHMpICsgCiAgbGFicyh4ID0gIkxhdGl0dWRlIiwgCiAgICAgICB5ID0gIkdlbmVyYXRpb25zIGJldHdlZW4gXG5jb2xsZWN0aW9ucyIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKGZyb20gPSAwLCB0byA9IDIxLCBieSA9IDUpKSArIAogIHRoZW1lX21hdHQoKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpCmBgYAoKYGBge3IgcmFuay1zaW1zLCBmaWcud2lkdGg9MTgsIGZpZy5oZWlnaHQ9OH0Kb2JzX3JhbmtzID0gZ2dwbG90KGZ1bGxfZGF0YSwgYWVzKHggPSByYW5rKSkgKyAKICBmYWNldF93cmFwKHR1YmV+LikgKyAKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEpICsgCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMiw0LDYsOCwxMCkpICsgCiAgZ2d0aXRsZSgiT2JzZXJ2YXRpb24iKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkKCnNpbV9kYXRhID0gZGF0YS5mcmFtZSgpCmZvcihpIGluIDE6bWF4KGZ1bGxfZGF0YSRydW4pKXsKICByZXBfZGF0YSA9IGRhdGEuZnJhbWUoInR1YmUiID0gc2FtcGxlKGMoMToxMCksIHNpemUgPSAxMCwgcmVwbGFjZSA9IEYpLCAKICAgICAgICAgICAgICAgICAgICAgICAgInJhbmsiID0gYygxOjEwKSwKICAgICAgICAgICAgICAgICAgICAgICAgInJlcCIgPSBpKSAlPiUgCiAgICBhcnJhbmdlKHR1YmUpCiAgCiAgc2ltX2RhdGEgPSBiaW5kX3Jvd3Moc2ltX2RhdGEsIHJlcF9kYXRhKQogIAp9CgpzaW1fcmFua3MgPSBnZ3Bsb3Qoc2ltX2RhdGEsIGFlcyh4ID0gcmFuaykpICsgCiAgZmFjZXRfd3JhcCh0dWJlfi4pICsgCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxKSArIAogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKDIsNCw2LDgsMTApKSArIAogIGdndGl0bGUoIlNpbXVsYXRpb24iKSArIAogIHRoZW1lX21hdHRfZmFjZXRzKCkKCgpnZ2FycmFuZ2Uob2JzX3JhbmtzLCBzaW1fcmFua3MpCmBgYAoK